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

pantsbuild / pants / 19015773527

02 Nov 2025 05:33PM UTC coverage: 17.872% (-62.4%) from 80.3%
19015773527

Pull #22816

github

web-flow
Merge a12d75757 into 6c024e162
Pull Request #22816: Update Pants internal Python to 3.14

4 of 5 new or added lines in 3 files covered. (80.0%)

28452 existing lines in 683 files now uncovered.

9831 of 55007 relevant lines covered (17.87%)

0.18 hits per line

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

0.0
/src/python/pants/backend/python/lint/flake8/subsystem.py
1
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

UNCOV
4
from __future__ import annotations
×
5

UNCOV
6
from dataclasses import dataclass
×
7

UNCOV
8
from pants.backend.python.lint.first_party_plugins import (
×
9
    BaseFirstPartyPlugins,
10
    resolve_first_party_plugins,
11
)
UNCOV
12
from pants.backend.python.lint.flake8.skip_field import SkipFlake8Field
×
UNCOV
13
from pants.backend.python.subsystems.python_tool_base import PythonToolBase
×
UNCOV
14
from pants.backend.python.target_types import (
×
15
    ConsoleScript,
16
    InterpreterConstraintsField,
17
    PythonResolveField,
18
    PythonSourceField,
19
)
UNCOV
20
from pants.backend.python.util_rules import python_sources
×
UNCOV
21
from pants.core.goals.resolves import ExportableTool
×
UNCOV
22
from pants.core.util_rules.config_files import ConfigFilesRequest
×
UNCOV
23
from pants.engine.addresses import UnparsedAddressInputs
×
UNCOV
24
from pants.engine.rules import collect_rules, rule
×
UNCOV
25
from pants.engine.target import FieldSet, Target
×
UNCOV
26
from pants.engine.unions import UnionRule
×
UNCOV
27
from pants.option.option_types import (
×
28
    ArgsListOption,
29
    BoolOption,
30
    FileListOption,
31
    FileOption,
32
    SkipOption,
33
    TargetListOption,
34
)
UNCOV
35
from pants.util.docutil import doc_url
×
UNCOV
36
from pants.util.logging import LogLevel
×
UNCOV
37
from pants.util.strutil import softwrap
×
38

39

UNCOV
40
@dataclass(frozen=True)
×
UNCOV
41
class Flake8FieldSet(FieldSet):
×
UNCOV
42
    required_fields = (PythonSourceField,)
×
43

UNCOV
44
    source: PythonSourceField
×
UNCOV
45
    interpreter_constraints: InterpreterConstraintsField
×
UNCOV
46
    resolve: PythonResolveField
×
47

UNCOV
48
    @classmethod
×
UNCOV
49
    def opt_out(cls, tgt: Target) -> bool:
×
50
        return tgt.get(SkipFlake8Field).value
×
51

52

UNCOV
53
class Flake8(PythonToolBase):
×
UNCOV
54
    options_scope = "flake8"
×
UNCOV
55
    name = "Flake8"
×
UNCOV
56
    help_short = "The Flake8 Python linter (https://flake8.pycqa.org/)."
×
57

UNCOV
58
    default_main = ConsoleScript("flake8")
×
UNCOV
59
    default_requirements = ["flake8>=5.0.4,<7"]
×
60

UNCOV
61
    default_lockfile_resource = ("pants.backend.python.lint.flake8", "flake8.lock")
×
62

UNCOV
63
    skip = SkipOption("lint")
×
UNCOV
64
    args = ArgsListOption(example="--ignore E123,W456 --enable-extensions H111")
×
UNCOV
65
    config = FileOption(
×
66
        default=None,
67
        advanced=True,
68
        help=lambda cls: softwrap(
69
            f"""
70
            Path to an INI config file understood by Flake8
71
            (https://flake8.pycqa.org/en/latest/user/configuration.html).
72

73
            Setting this option will disable `[{cls.options_scope}].config_discovery`. Use
74
            this option if the config is located in a non-standard location.
75
            """
76
        ),
77
    )
UNCOV
78
    extra_files = FileListOption(
×
79
        default=None,
80
        advanced=True,
81
        help=softwrap(
82
            """Paths to extra files to include in the sandbox. This can be useful for Flake8 plugins,
83
            like including config files for the `flake8-bandit` plugin."""
84
        ),
85
    )
UNCOV
86
    config_discovery = BoolOption(
×
87
        default=True,
88
        advanced=True,
89
        help=lambda cls: softwrap(
90
            f"""
91
            If true, Pants will include any relevant config files during
92
            runs (`.flake8`, `flake8`, `setup.cfg`, and `tox.ini`).
93

94
            Use `[{cls.options_scope}].config` instead if your config is in a
95
            non-standard location.
96
            """
97
        ),
98
    )
UNCOV
99
    _source_plugins = TargetListOption(
×
100
        advanced=True,
101
        help=softwrap(
102
            f"""
103
            An optional list of `python_sources` target addresses to load first-party plugins.
104

105
            You must set the plugin's parent directory as a source root. For
106
            example, if your plugin is at `build-support/flake8/custom_plugin.py`, add
107
            `'build-support/flake8'` to `[source].root_patterns` in `pants.toml`. This is
108
            necessary for Pants to know how to tell Flake8 to discover your plugin. See
109
            {doc_url("docs/using-pants/key-concepts/source-roots")}
110

111
            You must also set `[flake8:local-plugins]` in your Flake8 config file.
112

113
            For example:
114

115
                [flake8:local-plugins]
116
                extension =
117
                CUSTOMCODE = custom_plugin:MyChecker
118

119
            While your plugin's code can depend on other first-party code and third-party
120
            requirements, all first-party dependencies of the plugin must live in the same
121
            directory or a subdirectory.
122

123
            To instead load third-party plugins, add them to a custom resolve alongside
124
            flake8 itself, as described in {doc_url("docs/python/overview/lockfiles#lockfiles-for-tools")}.
125
            """
126
        ),
127
    )
128

UNCOV
129
    @property
×
UNCOV
130
    def config_request(self) -> ConfigFilesRequest:
×
131
        # See https://flake8.pycqa.org/en/latest/user/configuration.html#configuration-locations
132
        # for how Flake8 discovers config files.
133
        return ConfigFilesRequest(
×
134
            specified=self.config,
135
            specified_option_name=f"[{self.options_scope}].config",
136
            discovery=self.config_discovery,
137
            check_existence=["flake8", ".flake8"],
138
            check_content={"setup.cfg": b"[flake8]", "tox.ini": b"[flake8]"},
139
        )
140

UNCOV
141
    @property
×
UNCOV
142
    def source_plugins(self) -> UnparsedAddressInputs:
×
143
        return UnparsedAddressInputs(
×
144
            self._source_plugins,
145
            owning_address=None,
146
            description_of_origin=f"the option `[{self.options_scope}].source_plugins`",
147
        )
148

149

150
# --------------------------------------------------------------------------------------
151
# First-party plugins
152
# --------------------------------------------------------------------------------------
153

154

UNCOV
155
class Flake8FirstPartyPlugins(BaseFirstPartyPlugins):
×
UNCOV
156
    pass
×
157

158

UNCOV
159
@rule(desc="Prepare [flake8].source_plugins", level=LogLevel.DEBUG)
×
UNCOV
160
async def flake8_first_party_plugins(flake8: Flake8) -> Flake8FirstPartyPlugins:
×
161
    return await resolve_first_party_plugins(flake8.source_plugins, Flake8FirstPartyPlugins)
×
162

163

UNCOV
164
def rules():
×
UNCOV
165
    return (
×
166
        *collect_rules(),
167
        *python_sources.rules(),
168
        UnionRule(ExportableTool, Flake8),
169
    )
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

© 2025 Coveralls, Inc