diff --git a/CHANGES b/CHANGES index 46aa5b8..ad41026 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,25 @@ $ pip install --user --upgrade --pre gp-libs - _Add your latest changes from PRs here_ +### Development + +- Strengthen linting (#31) + + - Add flake8-commas (COM) + + - https://docs.astral.sh/ruff/rules/#flake8-commas-com + - https://pypi.org/project/flake8-commas/ + + - Add flake8-builtins (A) + + - https://docs.astral.sh/ruff/rules/#flake8-builtins-a + - https://pypi.org/project/flake8-builtins/ + + - Add flake8-errmsg (EM) + + - https://docs.astral.sh/ruff/rules/#flake8-errmsg-em + - https://pypi.org/project/flake8-errmsg/ + ## gp-libs 0.0.6post0 (2024-02-01) ### Packaging diff --git a/docs/conf.py b/docs/conf.py index c9e88e0..4bec42c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,7 +52,7 @@ master_doc = "index" project = about["__title__"] -copyright = about["__copyright__"] +project_copyright = about["__copyright__"] version = "%s" % (".".join(about["__version__"].split("."))[:2]) release = "%s" % (about["__version__"]) @@ -95,7 +95,7 @@ "sidebar/navigation.html", "sidebar/projects.html", "sidebar/scroll-end.html", - ] + ], } # linkify_issues diff --git a/pyproject.toml b/pyproject.toml index cf727dc..a8ee068 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,8 +93,11 @@ select = [ "F", # pyflakes "I", # isort "UP", # pyupgrade + "A", # flake8-builtins "B", # flake8-bugbear "C4", # flake8-comprehensions + "COM", # flake8-commas + "EM", # flake8-errmsg "Q", # flake8-quotes "PTH", # flake8-use-pathlib "SIM", # flake8-simplify @@ -103,6 +106,9 @@ select = [ "RUF", # Ruff-specific rules "D", # pydocstyle ] +ignore = [ + "COM812", # missing trailing comma, ruff format conflict +] [tool.ruff.lint.isort] known-first-party = [ diff --git a/src/doctest_docutils.py b/src/doctest_docutils.py index 451e572..f0e3b46 100644 --- a/src/doctest_docutils.py +++ b/src/doctest_docutils.py @@ -126,7 +126,8 @@ def run(self) -> t.List[Node]: node["options"][flag] = True # Skip the test except InvalidSpecifier: self.state.document.reporter.warning( - "'%s' is not a valid pyversion option" % spec, line=self.lineno + "'%s' is not a valid pyversion option" % spec, + line=self.lineno, ) if "skipif" in self.options: node["skipif"] = self.options["skipif"] @@ -198,7 +199,7 @@ class DocTestFinderNameDoesNotExist(ValueError): def __init__(self, string: str): return super().__init__( "DocTestFinder.find: name must be given " - f"when string.__name__ doesn't exist: {type(string)!r}" + f"when string.__name__ doesn't exist: {type(string)!r}", ) @@ -298,8 +299,8 @@ def _find( "source_lines": source_lines, "globs": globs, "seen": seen, - } - ) + }, + ), ) ext = pathlib.Path(name).suffix logger.debug(f"parse, ext: {ext}") @@ -328,7 +329,8 @@ def _find( settings = OptionParser(components=(Parser,)).get_default_values() doc = docutils.utils.new_document( - source_path=str(source_path), settings=settings + source_path=str(source_path), + settings=settings, ) parser.parse(string, doc) @@ -371,7 +373,9 @@ def condition(node: Node) -> bool: if sys.version_info < (3, 13): def _from_module( - self, module: t.Optional[t.Union[str, types.ModuleType]], object: object + self, + module: t.Optional[t.Union[str, types.ModuleType]], + object: object, # NOQA: A002 ) -> bool: """Return true if the given object lives in the given module. @@ -386,7 +390,7 @@ def _from_module( # Type ignored because this is a private function. return t.cast( bool, - super()._from_module(module, object), # type:ignore[misc] + super()._from_module(module, object), # type:ignore[misc] # NOQA: A002 ) else: # pragma: no cover @@ -412,7 +416,7 @@ class TestDocutilsPackageRelativeError(Exception): def __init__(self) -> None: return super().__init__( - "Package may only be specified for module-relative paths." + "Package may only be specified for module-relative paths.", ) @@ -442,7 +446,10 @@ def testdocutils( # 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. text, _ = doctest._load_testfile( # type: ignore - filename, package, module_relative, encoding or "utf-8" + filename, + package, + module_relative, + encoding or "utf-8", ) # If no name was given, then use the file's name. diff --git a/src/linkify_issues.py b/src/linkify_issues.py index c7a60ba..49c6b77 100644 --- a/src/linkify_issues.py +++ b/src/linkify_issues.py @@ -33,7 +33,8 @@ def condition(node: nodes.Node) -> bool: isinstance(node, nodes.Text) and len(re.findall(issue_re, node.astext())) > 0 ) and not isinstance( - node.parent, (nodes.literal, nodes.FixedTextElement, nodes.reference) + node.parent, + (nodes.literal, nodes.FixedTextElement, nodes.reference), ) return cond @@ -74,7 +75,9 @@ def setup(app: Sphinx) -> SetupDict: app.add_transform(LinkifyIssues) app.add_config_value("issue_re", re.compile(DEFAULT_ISSUE_RE), "env") app.add_config_value( - "issue_url_tpl", r"https://github.com/git-pull/gp-libs/issues/{issue_id}", "env" + "issue_url_tpl", + r"https://github.com/git-pull/gp-libs/issues/{issue_id}", + "env", ) return SetupDict( @@ -82,5 +85,5 @@ def setup(app: Sphinx) -> SetupDict: "version": "0.1", "parallel_read_safe": True, "parallel_write_safe": True, - } + }, ) diff --git a/src/pytest_doctest_docutils.py b/src/pytest_doctest_docutils.py index ab04690..a98e97d 100644 --- a/src/pytest_doctest_docutils.py +++ b/src/pytest_doctest_docutils.py @@ -72,7 +72,8 @@ def pytest_unconfigure() -> None: def pytest_collect_file( - file_path: pathlib.Path, parent: pytest.Collector + file_path: pathlib.Path, + parent: pytest.Collector, ) -> t.Optional[t.Union["DocTestDocutilsFile", "_pytest.doctest.DoctestModule"]]: """Test collector for pytest-doctest-docutils.""" config = parent.config @@ -82,10 +83,11 @@ def pytest_collect_file( ( _pytest.doctest._is_setup_py(file_path), _pytest.doctest._is_main_py(file_path), - ) + ), ): mod: t.Union[ - DocTestDocutilsFile, _pytest.doctest.DoctestModule + DocTestDocutilsFile, + _pytest.doctest.DoctestModule, ] = _pytest.doctest.DoctestModule.from_parent(parent, path=file_path) return mod elif _is_doctest(config, file_path, parent): @@ -94,7 +96,9 @@ def pytest_collect_file( def _is_doctest( - config: pytest.Config, path: pathlib.Path, parent: pytest.Collector + config: pytest.Config, + path: pathlib.Path, + parent: pytest.Collector, ) -> bool: if path.suffix in (".rst", ".md") and parent.session.isinitpath(path): return True @@ -142,7 +146,9 @@ def report_unexpected_exception( test: "doctest.DocTest", example: "doctest.Example", exc_info: t.Tuple[ - t.Type[BaseException], BaseException, types.TracebackType + t.Type[BaseException], + BaseException, + types.TracebackType, ], ) -> None: if isinstance(exc_info[1], OutcomeException): @@ -247,7 +253,9 @@ class DocutilsDocTestRunner(doctest.DocTestRunner): """DocTestRunner for doctest_docutils.""" def summarize( # type: ignore - self, out: "_Out", verbose: t.Optional[bool] = None + self, + out: "_Out", + verbose: t.Optional[bool] = None, ) -> t.Tuple[int, int]: """Summarize the test runs.""" string_io = io.StringIO() @@ -261,7 +269,9 @@ def summarize( # type: ignore return res def _DocTestRunner__patched_linecache_getlines( - self, filename: str, module_globals: t.Any = None + self, + filename: str, + module_globals: t.Any = None, ) -> t.Any: # this is overridden from DocTestRunner adding the try-except below m = self._DocTestRunner__LINECACHE_FILENAME_RE.match(filename) # type: ignore diff --git a/tests/test_doctest_docutils.py b/tests/test_doctest_docutils.py index 4b6335b..8e66b17 100644 --- a/tests/test_doctest_docutils.py +++ b/tests/test_doctest_docutils.py @@ -32,8 +32,8 @@ class DocTestFinderFixture(t.NamedTuple): """ >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -46,8 +46,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -63,8 +63,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -77,8 +77,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -91,8 +91,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -106,8 +106,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ::: - """ - ) + """, + ), }, tests_found=1, ), @@ -121,8 +121,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -138,8 +138,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ::: - """ - ) + """, + ), }, tests_found=1, ), @@ -155,8 +155,8 @@ class DocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -179,8 +179,8 @@ class DocTestFinderFixture(t.NamedTuple): 6 ``` ```` - """ - ) + """, + ), }, tests_found=2, ), @@ -195,7 +195,9 @@ def __init__(self, file_path_mode: str) -> None: @pytest.mark.parametrize( - DocTestFinderFixture._fields, FIXTURES, ids=[f.test_id for f in FIXTURES] + DocTestFinderFixture._fields, + FIXTURES, + ids=[f.test_id for f in FIXTURES], ) @pytest.mark.parametrize("file_path_mode", ["relative", "absolute"]) def test_DocutilsDocTestFinder( @@ -230,7 +232,10 @@ def test_DocutilsDocTestFinder( # Test finder = doctest_docutils.DocutilsDocTestFinder() text, _ = doctest._load_testfile( # type: ignore - str(first_test_filename), package=None, module_relative=False, encoding="utf-8" + str(first_test_filename), + package=None, + module_relative=False, + encoding="utf-8", ) tests = finder.find(text, str(first_test_filename)) tests.sort(key=lambda test: test.name) diff --git a/tests/test_linkify_issues.py b/tests/test_linkify_issues.py index f8e5c8d..41b9a23 100644 --- a/tests/test_linkify_issues.py +++ b/tests/test_linkify_issues.py @@ -40,7 +40,9 @@ class LinkTestFixture(t.NamedTuple): @pytest.mark.parametrize( - LinkTestFixture._fields, FIXTURES, ids=[f.test_id for f in FIXTURES] + LinkTestFixture._fields, + FIXTURES, + ids=[f.test_id for f in FIXTURES], ) def test_links_show( make_app: t.Callable[[t.Any], SphinxTestApp], diff --git a/tests/test_pytest_doctest_docutils.py b/tests/test_pytest_doctest_docutils.py index 2e4d64d..71fa05b 100644 --- a/tests/test_pytest_doctest_docutils.py +++ b/tests/test_pytest_doctest_docutils.py @@ -30,8 +30,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): """ >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -44,8 +44,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -61,8 +61,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -75,8 +75,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 - """ - ) + """, + ), }, tests_found=1, ), @@ -90,8 +90,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ::: - """ - ) + """, + ), }, tests_found=1, ), @@ -105,8 +105,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -122,8 +122,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ::: - """ - ) + """, + ), }, tests_found=1, ), @@ -139,8 +139,8 @@ class PytestDocTestFinderFixture(t.NamedTuple): >>> 4 + 4 8 ``` - """ - ) + """, + ), }, tests_found=1, ), @@ -160,8 +160,8 @@ def hello(statement: str) -> None: ''' print(statement) - """ - ) + """, + ), }, tests_found=1, ), @@ -184,8 +184,8 @@ def hello(statement: str) -> None: 6 ``` ```` - """ - ) + """, + ), }, tests_found=2, ), @@ -193,7 +193,9 @@ def hello(statement: str) -> None: @pytest.mark.parametrize( - PytestDocTestFinderFixture._fields, FIXTURES, ids=[f.test_id for f in FIXTURES] + PytestDocTestFinderFixture._fields, + FIXTURES, + ids=[f.test_id for f in FIXTURES], ) def test_pluginDocutilsDocTestFinder( pytester: _pytest.pytester.Pytester, @@ -212,7 +214,7 @@ def test_pluginDocutilsDocTestFinder( [pytest] addopts=-p no:doctest -vv - """.strip() + """.strip(), ), ) tests_path = pytester.path / "tests" @@ -247,7 +249,7 @@ def test_conftest_py( [pytest] addopts=-p no:doctest -vv - """.strip() + """.strip(), ), ) pytester.makeconftest( @@ -267,8 +269,8 @@ def add_doctest_fixtures( def add(a: int, b: int) -> int: return a + b doctest_namespace["add"] = add - """ - ) + """, + ), ) tests_path = pytester.path / "tests" files = { @@ -282,8 +284,8 @@ def hello(statement: str) -> None: ''' print(statement) - """ - ) + """, + ), } first_test_key = next(iter(files.keys())) first_test_filename = str(tests_path / first_test_key) @@ -319,7 +321,7 @@ def test_conftest_md( [pytest] addopts=-p no:doctest -vv - """.strip() + """.strip(), ), ) pytester.makeconftest( @@ -339,8 +341,8 @@ def add_doctest_fixtures( def add(a: int, b: int) -> int: return a + b doctest_namespace["add"] = add - """ - ) + """, + ), ) tests_path = pytester.path / "tests" files = { @@ -375,8 +377,8 @@ def add(a: int, b: int) -> int: >>> add(5, 1) 6 ``` - """ - ) + """, + ), } first_test_key = next(iter(files.keys())) first_test_filename = str(tests_path / first_test_key)