Skip to content
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

Maintenance updates: docformatter fixes, and mypy/docs updates #53

Merged
merged 5 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ jobs:
test:
runs-on: ${{ matrix.os }}
needs: package
timeout-minutes: 15

strategy:
fail-fast: false
Expand Down Expand Up @@ -116,7 +117,7 @@ jobs:
path: ${{ env.PACKAGES_PATH }}

- name: pytest[${{ matrix.python }}]
run: dwas --verbose --only pytest[${{ matrix.python }}] -- --numprocesses auto
run: dwas --verbose --only pytest[${{ matrix.python }}] -- ${{ !startsWith(matrix.python, 'pypy') && '--numprocesses 2' || '' }}

- name: Move the coverage to another place to avoid conflicts
if: runner.os != 'Linux'
Expand Down
4 changes: 2 additions & 2 deletions docs/_extensions/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
}


class AnsiMonokaiStyle(monokai.MonokaiStyle): # type: ignore
class AnsiMonokaiStyle(monokai.MonokaiStyle):
styles = dict(monokai.MonokaiStyle.styles)
styles.update(color_tokens(fg_colors, bg_colors))
styles[pygments.token.Token.Color.Faint.Cyan] = "#0867AC"


class AnsiDefaultStyle(default.DefaultStyle): # type: ignore
class AnsiDefaultStyle(default.DefaultStyle):
styles = dict(default.DefaultStyle.styles)
styles.update(color_tokens(fg_colors, bg_colors))
styles[pygments.token.Token.Color.Faint.Cyan] = "#0867AC"
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
.. _submit an issue: https://github.com/BenjaminSchubert/dwas/issues/new
.. _the Black formatter: https://black.readthedocs.io/en/stable/
.. _the isort formatter: https://pycqa.github.io/isort/
.. _coverage.py: https://coverage.readthedocs.io/en/stable/
.. _coverage.py: https://coverage.readthedocs.io/en/latest/
.. _docformatter: https://github.com/PyCQA/docformatter/
.. _mypy: https://mypy.readthedocs.io/en/stable/
.. _pylint: https://pylint.pycqa.org/en/latest/
Expand All @@ -136,7 +136,7 @@
.. _the Unimport formatter: https://unimport.hakancelik.dev/
.. _the manylinux project: https://github.com/pypa/manylinux
.. _github actions: https://github.com/features/actions
.. _pipx: https://pypa.github.io/pipx/
.. _pipx: https://pipx.pypa.io/stable/
.. _PyPI: https://pypi.org/project/dwas/
.. _tox: https://tox.wiki/
.. _nox: https://nox.thea.codes/
Expand Down
7 changes: 6 additions & 1 deletion dwasfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
description="Show which imports are unnecessary",
)
dwas.register_managed_step(dwas.predefined.isort(files=PYTHON_FILES))
dwas.register_managed_step(dwas.predefined.docformatter(files=PYTHON_FILES))
dwas.register_managed_step(
dwas.predefined.docformatter(files=PYTHON_FILES),
dependencies=["docformatter[tomli]<1.7.1"],
)
dwas.register_managed_step(dwas.predefined.black())
dwas.register_step_group(
"format-check", ["black", "docformatter", "isort", "unimport"]
Expand All @@ -57,9 +60,11 @@
dwas.predefined.docformatter(
additional_arguments=["--recursive", "--diff", "--in-place"],
files=PYTHON_FILES,
expected_status_codes=[0, 3],
),
name="docformatter:fix",
run_by_default=False,
dependencies=["docformatter[tomli]<1.7.1"],
requires=["isort:fix"],
)
dwas.register_managed_step(
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ recursive = true
make-summary-multi-line = true
pre-summary-newline = true
wrap-summaries = 89
wrap-descriptions = 72

##
# Isort
Expand Down
12 changes: 5 additions & 7 deletions src/dwas/_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def expand(steps: List[str]) -> Set[str]:
def compute_replacement(requirements: List[str]) -> List[str]:
replacements = []
for requirement in requirements:
if requirement in cast(List[str], steps):
if requirement in steps:
replacements.append(requirement)
else:
if requirement not in except_replacements:
Expand Down Expand Up @@ -430,12 +430,10 @@ def _execute(
future = cast(
"futures.Future[None]",
executor.submit(
# XXX: mypy gets confused here, but the result is
# sane
copy_context().run, # type: ignore[arg-type]
self._run_step, # type: ignore[arg-type]
step, # type: ignore[arg-type]
pipe_plexer, # type: ignore[arg-type]
copy_context().run,
self._run_step,
step,
pipe_plexer,
),
)
running_futures[future] = step, pipe_plexer
Expand Down
21 changes: 13 additions & 8 deletions src/dwas/_steps/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,12 @@ def setup_dependent(
"""
Run some logic into a dependent step.

:param original_step: The original step handler that was used when the
step defining this method was called.
:param original_step: The original step handler that was used
when the step defining this method was
called.
:param current_step: The current step handler, that contains the
context of the step that is going to be executed.
context of the step that is going to be
executed.
"""


Expand Down Expand Up @@ -358,10 +360,12 @@ def gather_artifacts(self, step: "StepRunner") -> Dict[str, List[Any]]:
"""
Gather all artifacts exposed by this step.

:param step: The step handler that was used when running the step.
:return: A dictionary of artifact key to a list of arbitrary data.
This **must** return a list, as they are merged with other
steps' artifacts into a single list per artifact key.
:param step: The step handler that was used when running the
step.
:return: A dictionary of artifact key to a list of arbitrary
data. This **must** return a list, as they are merged
with other steps' artifacts into a single list per
artifact key.
"""


Expand Down Expand Up @@ -465,7 +469,8 @@ def cache_path(self) -> Path:
"""
The path to the cache for the current step.

This can be used to store temporary files or any other artifacts.
This can be used to store temporary files or any other
artifacts.

This will be cleaned up and emptied before the step runs.
"""
Expand Down
26 changes: 24 additions & 2 deletions src/dwas/predefined/_docformatter.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import logging
import subprocess
from typing import List, Optional, Sequence

# XXX: All imports here should be done from the top level. If we need it,
# users might need it
from .. import Step, StepRunner, build_parameters, set_defaults

LOGGER = logging.getLogger(__name__)


@set_defaults(
{
"dependencies": ["docformatter"],
"additional_arguments": ["--recursive", "--check", "--diff"],
"files": ["."],
"expected_status_codes": [0],
}
)
class DocFormatter(Step):
Expand All @@ -20,15 +25,25 @@ def __call__(
self,
step: StepRunner,
files: Sequence[str],
additional_arguments: List[str],
additional_arguments: Sequence[str],
expected_status_codes: Sequence[int],
) -> None:
step.run(["docformatter", *additional_arguments, *files])
try:
step.run(["docformatter", *additional_arguments, *files])
except subprocess.CalledProcessError as exc:
if exc.returncode not in expected_status_codes:
raise
LOGGER.debug(
"Ignoring error code %d from subprocess, as it is expected",
exc.returncode,
)


def docformatter(
*,
files: Optional[Sequence[str]] = None,
additional_arguments: Optional[List[str]] = None,
expected_status_codes: Optional[List[int]] = None,
) -> Step:
"""
Run `docformatter`_ against your python source code.
Expand All @@ -41,6 +56,11 @@ def docformatter(
:param additional_arguments: Additional arguments to pass to the ``docformatter``
invocation.
Defaults to :python:`["--recursive"]`.
:param expected_status_codes: Status codes that are acceptable from ``docformatter``.
Defaults to :python:`[0]`. When formatting in
place, you might want to set to :python:`[0, 3]`,
as ``docformatter`` always returns 3 if a file
was modified.
:return: The step so that you can add additional parameters to it if needed.

:Examples:
Expand All @@ -66,6 +86,7 @@ def docformatter(
# code by ``:fix``
name="docformatter:fix",
additional_arguments=["--in-place"],
expected_status_codes=[0, 3],
run_by_default=False,
files=["src,", "tests", "dwasfile.py", "setup.py"],
)
Expand All @@ -74,4 +95,5 @@ def docformatter(
return build_parameters(
files=files,
additional_arguments=additional_arguments,
expected_status_codes=expected_status_codes,
)(DocFormatter())
4 changes: 3 additions & 1 deletion tests/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ def execute(args: List[str], expected_status: int = 0) -> Result:
print(out)
print(err, file=sys.stderr)

assert exit_code == expected_status
assert (
exit_code == expected_status
), f"Unexpected return code {exit_code} != {expected_status} for 'dwas {' '.join(args)}'."
return Result(exc=exception, stdout=out, stderr=err)


Expand Down
11 changes: 6 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ def ensure_defaults_are_untouched(tmp_path_factory):
"""
Ensure that the defaults values for predefined steps are not mutated.

The predefined steps set some defaults that might be mutable, e.g. lists.
We need to take special care to ensure we do not modify them at runtime so
that the steps are reusable.
The predefined steps set some defaults that might be mutable, e.g.
lists. We need to take special care to ensure we do not modify them
at runtime so that the steps are reusable.

This loads all the steps before anything runs, and deep copies the defaults.
It then validates that they did not change at the end of the run.
This loads all the steps before anything runs, and deep copies the
defaults. It then validates that they did not change at the end of
the run.
"""
steps = {}

Expand Down
5 changes: 4 additions & 1 deletion tests/predefined/test_docformatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ class TestDocformatter(BaseFormatterTest):

register_managed_step(docformatter())
register_managed_step(
docformatter(additional_arguments=["--recursive", "--in-place"]),
docformatter(
additional_arguments=["--recursive", "--in-place"],
expected_status_codes=[0, 3],
),
name="docformatter:fix",
run_by_default=False,
)
Expand Down