• 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/isort/rules.py
1
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
UNCOV
3
from __future__ import annotations
×
4

UNCOV
5
from dataclasses import dataclass
×
6

UNCOV
7
from pants.backend.python.lint.isort.skip_field import SkipIsortField
×
UNCOV
8
from pants.backend.python.lint.isort.subsystem import Isort
×
UNCOV
9
from pants.backend.python.target_types import PythonSourceField
×
UNCOV
10
from pants.backend.python.util_rules import pex
×
UNCOV
11
from pants.backend.python.util_rules.pex import (
×
12
    VenvPexProcess,
13
    create_venv_pex,
14
    determine_venv_pex_resolve_info,
15
)
UNCOV
16
from pants.core.goals.fmt import FmtResult, FmtTargetsRequest
×
UNCOV
17
from pants.core.util_rules.config_files import find_config_file
×
UNCOV
18
from pants.core.util_rules.partitions import PartitionerType
×
UNCOV
19
from pants.engine.fs import MergeDigests
×
UNCOV
20
from pants.engine.intrinsics import merge_digests
×
UNCOV
21
from pants.engine.process import ProcessExecutionFailure, execute_process_or_raise
×
UNCOV
22
from pants.engine.rules import collect_rules, concurrently, implicitly, rule
×
UNCOV
23
from pants.engine.target import FieldSet, Target
×
UNCOV
24
from pants.option.global_options import KeepSandboxes
×
UNCOV
25
from pants.util.logging import LogLevel
×
UNCOV
26
from pants.util.strutil import pluralize
×
27

28

UNCOV
29
@dataclass(frozen=True)
×
UNCOV
30
class IsortFieldSet(FieldSet):
×
UNCOV
31
    required_fields = (PythonSourceField,)
×
32

UNCOV
33
    source: PythonSourceField
×
34

UNCOV
35
    @classmethod
×
UNCOV
36
    def opt_out(cls, tgt: Target) -> bool:
×
37
        return tgt.get(SkipIsortField).value
×
38

39

UNCOV
40
class IsortRequest(FmtTargetsRequest):
×
UNCOV
41
    field_set_type = IsortFieldSet
×
UNCOV
42
    tool_subsystem = Isort  # type: ignore[assignment]
×
UNCOV
43
    partitioner_type = PartitionerType.DEFAULT_SINGLE_PARTITION
×
44

45

UNCOV
46
def generate_argv(
×
47
    source_files: tuple[str, ...], isort: Isort, *, is_isort5: bool
48
) -> tuple[str, ...]:
49
    args = [*isort.args]
×
50
    if is_isort5 and len(isort.config) == 1:
×
51
        explicitly_configured_config_args = [
×
52
            arg
53
            for arg in isort.args
54
            if (
55
                arg.startswith("--sp")
56
                or arg.startswith("--settings-path")
57
                or arg.startswith("--settings-file")
58
                or arg.startswith("--settings")
59
            )
60
        ]
61
        # TODO: Deprecate manually setting this option, but wait until we deprecate
62
        #  `[isort].config` to be a string rather than list[str] option.
63
        if not explicitly_configured_config_args:
×
64
            args.append(f"--settings={isort.config[0]}")
×
65
    args.extend(source_files)
×
66
    return tuple(args)
×
67

68

UNCOV
69
@rule(desc="Format with isort", level=LogLevel.DEBUG)
×
UNCOV
70
async def isort_fmt(
×
71
    request: IsortRequest.Batch, isort: Isort, keep_sandboxes: KeepSandboxes
72
) -> FmtResult:
73
    isort_pex_get = create_venv_pex(**implicitly(isort.to_pex_request()))
×
74
    config_files_get = find_config_file(isort.config_request(request.snapshot.dirs))
×
75
    isort_pex, config_files = await concurrently(isort_pex_get, config_files_get)
×
76

77
    # Isort 5+ changes how config files are handled. Determine which semantics we should use.
78
    is_isort5 = False
×
79
    if isort.config:
×
80
        isort_pex_info = await determine_venv_pex_resolve_info(isort_pex)
×
81
        isort_info = isort_pex_info.find("isort")
×
82
        is_isort5 = isort_info is not None and isort_info.version.major >= 5
×
83

84
    input_digest = await merge_digests(
×
85
        MergeDigests((request.snapshot.digest, config_files.snapshot.digest))
86
    )
87
    description = f"Run isort on {pluralize(len(request.files), 'file')}."
×
88
    result = await execute_process_or_raise(
×
89
        **implicitly(
90
            VenvPexProcess(
91
                isort_pex,
92
                argv=generate_argv(request.files, isort, is_isort5=is_isort5),
93
                input_digest=input_digest,
94
                output_files=request.files,
95
                description=description,
96
                level=LogLevel.DEBUG,
97
            )
98
        )
99
    )
100

101
    if b"Failed to pull configuration information" in result.stderr:
×
102
        raise ProcessExecutionFailure(
×
103
            -1,
104
            result.stdout,
105
            result.stderr,
106
            description,
107
            keep_sandboxes=keep_sandboxes,
108
        )
109

110
    return await FmtResult.create(request, result)
×
111

112

UNCOV
113
def rules():
×
UNCOV
114
    return (
×
115
        *collect_rules(),
116
        *IsortRequest.rules(),
117
        *pex.rules(),
118
    )
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