• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25443604553

06 May 2026 03:05PM UTC coverage: 92.879% (-0.04%) from 92.915%
25443604553

push

github

web-flow
[pants_ng] Scaffolding for a pants_ng mode. (#23319)

In this mode the command line is parsed as an
NG invocation, and dispatched appropriately.

Of course at the moment there are no
implementations to dispatch to. That will follow.

This does expose a new option, `pants_ng` to users. 
There is a big warning not to set it, but we're not trying
to hide that we're working on a new thing, so I am
comfortable with this.

25 of 76 new or added lines in 9 files covered. (32.89%)

1294 existing lines in 76 files now uncovered.

92234 of 99306 relevant lines covered (92.88%)

4.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/python/pants/backend/python/lint/docformatter/rules_integration_test.py
1
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
3✔
5

6
import pytest
3✔
7

8
from pants.backend.python import target_types_rules
3✔
9
from pants.backend.python.lint.docformatter.rules import DocformatterFieldSet, DocformatterRequest
3✔
10
from pants.backend.python.lint.docformatter.rules import rules as docformatter_rules
3✔
11
from pants.backend.python.lint.docformatter.subsystem import rules as docformatter_subsystem_rules
3✔
12
from pants.backend.python.target_types import PythonSourcesGeneratorTarget
3✔
13
from pants.core.goals.fmt import FmtResult
3✔
14
from pants.core.util_rules import source_files
3✔
15
from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest
3✔
16
from pants.engine.addresses import Address
3✔
17
from pants.engine.target import Target
3✔
18
from pants.testutil.python_interpreter_selection import all_major_minor_python_versions
3✔
19
from pants.testutil.rule_runner import QueryRule, RuleRunner
3✔
20

21

22
@pytest.fixture
3✔
23
def rule_runner() -> RuleRunner:
3✔
24
    return RuleRunner(
3✔
25
        rules=[
26
            *docformatter_rules(),
27
            *docformatter_subsystem_rules(),
28
            *source_files.rules(),
29
            *target_types_rules.rules(),
30
            QueryRule(FmtResult, (DocformatterRequest.Batch,)),
31
            QueryRule(SourceFiles, (SourceFilesRequest,)),
32
        ],
33
        target_types=[PythonSourcesGeneratorTarget],
34
    )
35

36

37
GOOD_FILE = '"""Good docstring."""\n'
3✔
38
BAD_FILE = '"""Oops, missing a period"""\n'
3✔
39
FIXED_BAD_FILE = '"""Oops, missing a period."""\n'
3✔
40

41

42
def run_docformatter(
3✔
43
    rule_runner: RuleRunner, targets: list[Target], *, extra_args: list[str] | None = None
44
) -> FmtResult:
45
    rule_runner.set_options(
3✔
46
        ["--backend-packages=pants.backend.python.lint.docformatter", *(extra_args or ())],
47
        env_inherit={"PATH", "PYENV_ROOT", "HOME"},
48
    )
49
    field_sets = [DocformatterFieldSet.create(tgt) for tgt in targets]
3✔
50
    input_sources = rule_runner.request(
3✔
51
        SourceFiles,
52
        [
53
            SourceFilesRequest(field_set.source for field_set in field_sets),
54
        ],
55
    )
56
    fmt_result = rule_runner.request(
3✔
57
        FmtResult,
58
        [
59
            DocformatterRequest.Batch(
60
                "",
61
                input_sources.snapshot.files,
62
                partition_metadata=None,
63
                snapshot=input_sources.snapshot,
64
            ),
65
        ],
66
    )
67
    return fmt_result
3✔
68

69

70
@pytest.mark.platform_specific_behavior
3✔
71
@pytest.mark.parametrize(
3✔
72
    "major_minor_interpreter",
73
    # Excluded due to https://github.com/pantsbuild/pants/issues/21718
74
    # lib2to3 is Officially Removed in 3.13, but some distributions of Python
75
    # remove it earlier See for example https://github.com/PyCQA/docformatter/issues/129
76
    all_major_minor_python_versions(["CPython>=3.9,<3.12"]),
77
)
78
def test_passing(rule_runner: RuleRunner, major_minor_interpreter: str) -> None:
3✔
79
    rule_runner.write_files({"f.py": GOOD_FILE, "BUILD": "python_sources(name='t')"})
3✔
80
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
3✔
81
    fmt_result = run_docformatter(
3✔
82
        rule_runner,
83
        [tgt],
84
        extra_args=[f"--docformatter-interpreter-constraints=['=={major_minor_interpreter}.*']"],
85
    )
86
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": GOOD_FILE})
3✔
87
    assert fmt_result.did_change is False
3✔
88

89

90
def test_failing(rule_runner: RuleRunner) -> None:
3✔
UNCOV
91
    rule_runner.write_files({"f.py": BAD_FILE, "BUILD": "python_sources(name='t')"})
1✔
UNCOV
92
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
1✔
UNCOV
93
    fmt_result = run_docformatter(rule_runner, [tgt])
1✔
UNCOV
94
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": FIXED_BAD_FILE})
1✔
UNCOV
95
    assert fmt_result.did_change is True
1✔
96

97

98
def test_multiple_targets(rule_runner: RuleRunner) -> None:
3✔
UNCOV
99
    rule_runner.write_files(
1✔
100
        {"good.py": GOOD_FILE, "bad.py": BAD_FILE, "BUILD": "python_sources(name='t')"}
101
    )
UNCOV
102
    tgts = [
1✔
103
        rule_runner.get_target(Address("", target_name="t", relative_file_path="good.py")),
104
        rule_runner.get_target(Address("", target_name="t", relative_file_path="bad.py")),
105
    ]
UNCOV
106
    fmt_result = run_docformatter(rule_runner, tgts)
1✔
UNCOV
107
    assert fmt_result.output == rule_runner.make_snapshot(
1✔
108
        {"good.py": GOOD_FILE, "bad.py": FIXED_BAD_FILE}
109
    )
UNCOV
110
    assert fmt_result.did_change is True
1✔
111

112

113
def test_respects_passthrough_args(rule_runner: RuleRunner) -> None:
3✔
UNCOV
114
    content = '"""\nOne line docstring acting like it\'s multiline.\n"""\n'
1✔
UNCOV
115
    rule_runner.write_files({"f.py": content, "BUILD": "python_sources(name='t')"})
1✔
UNCOV
116
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
1✔
UNCOV
117
    fmt_result = run_docformatter(
1✔
118
        rule_runner,
119
        [tgt],
120
        extra_args=["--docformatter-args='--make-summary-multi-line'"],
121
    )
UNCOV
122
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": content})
1✔
UNCOV
123
    assert fmt_result.did_change is False
1✔
124

125

126
def test_stub_files(rule_runner: RuleRunner) -> None:
3✔
UNCOV
127
    rule_runner.write_files(
1✔
128
        {"good.pyi": GOOD_FILE, "bad.pyi": BAD_FILE, "BUILD": "python_sources(name='t')"}
129
    )
130

UNCOV
131
    good_tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="good.pyi"))
1✔
UNCOV
132
    fmt_result = run_docformatter(rule_runner, [good_tgt])
1✔
UNCOV
133
    assert fmt_result.output == rule_runner.make_snapshot({"good.pyi": GOOD_FILE})
1✔
UNCOV
134
    assert not fmt_result.did_change
1✔
135

UNCOV
136
    bad_tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="bad.pyi"))
1✔
UNCOV
137
    fmt_result = run_docformatter(rule_runner, [bad_tgt])
1✔
UNCOV
138
    assert fmt_result.output == rule_runner.make_snapshot({"bad.pyi": FIXED_BAD_FILE})
1✔
UNCOV
139
    assert fmt_result.did_change
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc