• 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/yapf/rules_integration_test.py
1
# Copyright 2021 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.yapf.rules import YapfFieldSet, YapfRequest
3✔
10
from pants.backend.python.lint.yapf.rules import rules as yapf_rules
3✔
11
from pants.backend.python.lint.yapf.subsystem import Yapf
3✔
12
from pants.backend.python.lint.yapf.subsystem import rules as yapf_subsystem_rules
3✔
13
from pants.backend.python.target_types import PythonSourcesGeneratorTarget
3✔
14
from pants.core.goals.fmt import FmtResult
3✔
15
from pants.core.util_rules import config_files, source_files
3✔
16
from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest
3✔
17
from pants.engine.addresses import Address
3✔
18
from pants.engine.target import Target
3✔
19
from pants.testutil.python_interpreter_selection import all_major_minor_python_versions
3✔
20
from pants.testutil.rule_runner import QueryRule, RuleRunner
3✔
21

22

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

38

39
GOOD_FILE = "data = []\n"
3✔
40
BAD_FILE = "data = {  'a':11,'b':22    }\n"
3✔
41
FIXED_BAD_FILE = "data = {'a': 11, 'b': 22}\n"
3✔
42

43
# Note the indentation is 6 spaces; after formatting it should
44
# become 2 or 4 spaces depending on the configuration
45
NEEDS_CONFIG_FILE = "def func():\n      return 42\n"
3✔
46
FIXED_NEEDS_CONFIG_FILE_INDENT2 = "def func():\n  return 42\n"
3✔
47
FIXED_NEEDS_CONFIG_FILE_INDENT4 = "def func():\n    return 42\n"
3✔
48

49

50
def run_yapf(
3✔
51
    rule_runner: RuleRunner,
52
    targets: list[Target],
53
    *,
54
    extra_args: list[str] | None = None,
55
) -> FmtResult:
56
    rule_runner.set_options(
3✔
57
        ["--backend-packages=pants.backend.python.lint.yapf", *(extra_args or ())],
58
        env_inherit={"PATH", "PYENV_ROOT", "HOME"},
59
    )
60
    field_sets = [YapfFieldSet.create(tgt) for tgt in targets]
3✔
61
    input_sources = rule_runner.request(
3✔
62
        SourceFiles,
63
        [
64
            SourceFilesRequest(field_set.source for field_set in field_sets),
65
        ],
66
    )
67
    fmt_result = rule_runner.request(
3✔
68
        FmtResult,
69
        [
70
            YapfRequest.Batch(
71
                "",
72
                input_sources.snapshot.files,
73
                partition_metadata=None,
74
                snapshot=input_sources.snapshot,
75
            ),
76
        ],
77
    )
78
    return fmt_result
3✔
79

80

81
@pytest.mark.platform_specific_behavior
3✔
82
@pytest.mark.parametrize(
3✔
83
    "major_minor_interpreter",
84
    all_major_minor_python_versions(Yapf.default_interpreter_constraints),
85
)
86
def test_passing(rule_runner: RuleRunner, major_minor_interpreter: str) -> None:
3✔
87
    rule_runner.write_files({"f.py": GOOD_FILE, "BUILD": "python_sources(name='t')"})
3✔
88
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
3✔
89
    fmt_result = run_yapf(
3✔
90
        rule_runner,
91
        [tgt],
92
        extra_args=[f"--yapf-interpreter-constraints=['=={major_minor_interpreter}.*']"],
93
    )
94
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": GOOD_FILE})
3✔
95
    assert fmt_result.did_change is False
3✔
96

97

98
def test_failing(rule_runner: RuleRunner) -> None:
3✔
UNCOV
99
    rule_runner.write_files({"f.py": BAD_FILE, "BUILD": "python_sources(name='t')"})
1✔
UNCOV
100
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
1✔
UNCOV
101
    fmt_result = run_yapf(rule_runner, [tgt])
1✔
UNCOV
102
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": FIXED_BAD_FILE})
1✔
UNCOV
103
    assert fmt_result.did_change is True
1✔
104

105

106
def test_multiple_targets(rule_runner: RuleRunner) -> None:
3✔
UNCOV
107
    rule_runner.write_files(
1✔
108
        {"good.py": GOOD_FILE, "bad.py": BAD_FILE, "BUILD": "python_sources(name='t')"}
109
    )
UNCOV
110
    tgts = [
1✔
111
        rule_runner.get_target(Address("", target_name="t", relative_file_path="good.py")),
112
        rule_runner.get_target(Address("", target_name="t", relative_file_path="bad.py")),
113
    ]
UNCOV
114
    fmt_result = run_yapf(rule_runner, tgts)
1✔
UNCOV
115
    assert fmt_result.output == rule_runner.make_snapshot(
1✔
116
        {"good.py": GOOD_FILE, "bad.py": FIXED_BAD_FILE}
117
    )
UNCOV
118
    assert fmt_result.did_change is True
1✔
119

120

121
@pytest.mark.parametrize(
3✔
122
    "path,section,extra_args",
123
    (
124
        (".style.yapf", "style", []),
125
        ("custom.style", "style", ["--yapf-config=custom.style"]),
126
    ),
127
)
128
def test_config_file(
3✔
129
    rule_runner: RuleRunner, path: str, section: str, extra_args: list[str]
130
) -> None:
UNCOV
131
    rule_runner.write_files(
1✔
132
        {
133
            "f.py": NEEDS_CONFIG_FILE,
134
            "BUILD": "python_sources(name='t', interpreter_constraints=['==3.9.*'])",
135
            path: f"[{section}]\nindent_width = 2\n",
136
        }
137
    )
UNCOV
138
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
1✔
UNCOV
139
    fmt_result = run_yapf(rule_runner, [tgt], extra_args=extra_args)
1✔
UNCOV
140
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": FIXED_NEEDS_CONFIG_FILE_INDENT2})
1✔
UNCOV
141
    assert fmt_result.did_change is True
1✔
142

143

144
def test_passthrough_args(rule_runner: RuleRunner) -> None:
3✔
UNCOV
145
    rule_runner.write_files({"f.py": NEEDS_CONFIG_FILE, "BUILD": "python_sources(name='t')"})
1✔
UNCOV
146
    tgt = rule_runner.get_target(Address("", target_name="t", relative_file_path="f.py"))
1✔
UNCOV
147
    fmt_result = run_yapf(
1✔
148
        rule_runner, [tgt], extra_args=["--yapf-args=--style='{indent_width: 4}'"]
149
    )
UNCOV
150
    assert fmt_result.output == rule_runner.make_snapshot({"f.py": FIXED_NEEDS_CONFIG_FILE_INDENT4})
1✔
UNCOV
151
    assert fmt_result.did_change is True
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