• 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/dependency_inference/subsystem.py
1
# Copyright 2020 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 enum import Enum
×
7

UNCOV
8
from pants.core.util_rules.unowned_dependency_behavior import UnownedDependencyUsageOption
×
UNCOV
9
from pants.option.option_types import BoolOption, EnumOption, IntOption, StrListOption
×
UNCOV
10
from pants.option.subsystem import Subsystem
×
UNCOV
11
from pants.util.docutil import bin_name
×
UNCOV
12
from pants.util.strutil import softwrap
×
13

14

UNCOV
15
class InitFilesInference(Enum):
×
16
    """How to handle inference for __init__.py files."""
17

UNCOV
18
    always = "always"
×
UNCOV
19
    content_only = "content_only"
×
UNCOV
20
    never = "never"
×
21

22

UNCOV
23
class AmbiguityResolution(Enum):
×
24
    """How to resolve ambiguous symbol ownership."""
25

UNCOV
26
    none = "none"
×
UNCOV
27
    by_source_root = "by_source_root"
×
28

29

UNCOV
30
class PythonInferSubsystem(Subsystem):
×
UNCOV
31
    options_scope = "python-infer"
×
UNCOV
32
    help = "Options controlling which dependencies will be inferred for Python targets."
×
33

UNCOV
34
    imports = BoolOption(
×
35
        default=True,
36
        help=softwrap(
37
            """
38
            Infer a target's imported dependencies by parsing import statements from sources.
39

40
            To ignore a false positive, you can either put `# pants: no-infer-dep` on the line of
41
            the import or put `!{bad_address}` in the `dependencies` field of your target.
42
            """
43
        ),
44
    )
UNCOV
45
    string_imports = BoolOption(
×
46
        default=False,
47
        help=softwrap(
48
            """
49
            Infer a target's dependencies based on strings that look like dynamic
50
            dependencies, such as Django settings files expressing dependencies as strings or
51
            pytest plugins listed in the `pytest_plugins` variable in a test module or a
52
            conftest file.
53

54
            To ignore a false positive, you can either put `# pants: no-infer-dep` on the line of
55
            the string or put `!{bad_address}` in the `dependencies` field of your target.
56
            """
57
        ),
58
    )
UNCOV
59
    string_imports_min_dots = IntOption(
×
60
        default=2,
61
        help=softwrap(
62
            """
63
            If `--string-imports` is True, treat valid-looking strings with at least this many
64
            dots in them as potential dynamic dependencies. E.g., `'foo.bar.Baz'` will be
65
            treated as a potential dependency if this option is set to 2 but not if set to 3.
66
            """
67
        ),
68
    )
UNCOV
69
    assets = BoolOption(
×
70
        default=False,
71
        help=softwrap(
72
            """
73
            Infer a target's asset dependencies based on strings that look like Posix
74
            filepaths, such as those given to `open` or `pkgutil.get_data`.
75

76
            To ignore a false positive, you can either put `# pants: no-infer-dep` on the line of
77
            the string or put `!{bad_address}` in the `dependencies` field of your target.
78
            """
79
        ),
80
    )
UNCOV
81
    assets_min_slashes = IntOption(
×
82
        default=1,
83
        help=softwrap(
84
            """
85
            If `--assets` is True, treat valid-looking strings with at least this many forward
86
            slash characters as potential assets. E.g. `'data/databases/prod.db'` will be
87
            treated as a potential candidate if this option is set to 2 but not to 3.
88
            """
89
        ),
90
    )
UNCOV
91
    init_files = EnumOption(
×
92
        help=softwrap(
93
            f"""
94
            Infer a target's dependencies on any `__init__.py` files in the packages
95
            it is located in (recursively upward in the directory structure).
96

97
            Even if this is set to `never` or `content_only`, Pants will still always include any
98
            ancestor `__init__.py` files in the sandbox. Only, they will not be "proper"
99
            dependencies, e.g. they will not show up in `{bin_name()} dependencies` and their own
100
            dependencies will not be used.
101

102
            By default, Pants only adds a "proper" dependency if there is content in the
103
            `__init__.py` file. This makes sure that dependencies are added when likely necessary
104
            to build, while also avoiding adding unnecessary dependencies. While accurate, those
105
            unnecessary dependencies can complicate setting metadata like the
106
            `interpreter_constraints` and `resolve` fields.
107
            """
108
        ),
109
        default=InitFilesInference.content_only,
110
    )
UNCOV
111
    conftests = BoolOption(
×
112
        default=True,
113
        help=softwrap(
114
            """
115
            Infer a test target's dependencies on any `conftest.py` files in the current
116
            directory and ancestor directories.
117
            """
118
        ),
119
    )
UNCOV
120
    entry_points = BoolOption(
×
121
        default=True,
122
        help=softwrap(
123
            """
124
            Infer dependencies on targets' entry points, e.g. `pex_binary`'s
125
            `entry_point` field, `python_aws_lambda_function`'s `handler` field and
126
            `python_distribution`'s `entry_points` field.
127
            """
128
        ),
129
    )
UNCOV
130
    unowned_dependency_behavior = UnownedDependencyUsageOption(
×
131
        example_runtime_issue="`ModuleNotFoundError`",
132
        how_to_ignore="""
133
            either add `# pants: no-infer-dep` to the line of the
134
            import or put the import inside a `try: except ImportError:` block.
135
            """,
136
    )
UNCOV
137
    ambiguity_resolution = EnumOption(
×
138
        default=AmbiguityResolution.none,
139
        help=softwrap(
140
            f"""
141
            When multiple sources provide the same symbol, how to choose the provider to use.
142

143
            `{AmbiguityResolution.none.value}`: Do not attempt to resolve this ambiguity.
144
            No dependency will be inferred, and warnings will be logged.
145

146
            `{AmbiguityResolution.by_source_root.value}`:  Choose the provider with the closest
147
            common ancestor to the consumer's source root.  If the provider is under the same
148
            source root then this will be the source root itself.
149
            This is useful when multiple projects in different source roots provide the same
150
            symbols (because of repeated first-party module paths or overlapping
151
            requirements.txt) and you want to resolve the ambiguity locally in each project.
152
            """
153
        ),
154
    )
155

UNCOV
156
    ignored_unowned_imports = StrListOption(
×
157
        default=[],
158
        help=softwrap(
159
            """
160
            Unowned imports that should be ignored.
161

162
            If there are any unowned import statements and adding the `# pants: no-infer-dep`
163
            to the lines of the import is impractical, you can instead provide a list of imports
164
            that Pants should ignore. You can declare a specific import or a path to a package
165
            if you would like any of the package imports to be ignored.
166

167
            For example, you could ignore all the following imports of the code
168

169
                import src.generated.app
170
                from src.generated.app import load
171
                from src.generated.app import start
172
                from src.generated.client import connect
173

174
            by setting `ignored-unowned-imports=["src.generated.app", "src.generated.client.connect"]`.
175
            """
176
        ),
177
    )
178

UNCOV
179
    use_rust_parser = BoolOption(
×
180
        default=True,
181
        help=softwrap(
182
            f"""
183
            Use the new Rust-based, multithreaded, in-process dependency parser.
184

185
            Pants 2.17 introduced a new paradigm to dependency parsing for Python by leveraging a
186
            Rust-based parser that's called in the same process as Pants itself, instead of farming
187
            out to one-python-process-per-file.
188

189
            As a result of the switch, cold-cache performance improved by a factor of about 12x,
190
            while hot-cache had no difference. Additionally, Pants can now infer dependencies from
191
            Python scripts with syntax errors.
192

193
            After leaving this defaulted to disabled for a release cycle, Pants 2.18 started
194
            defaulting to enabling this.
195

196
            If you think the new behaviour is causing problems, it is recommended that you run
197
            `{bin_name()} peek :: > before.json` and then
198
            `{bin_name()} --python-infer-use-rust-parser=False peek :: > after.json` and compare the
199
            two results.
200

201
            If you think there is a bug and need to disable it, please file an issue:
202
            https://github.com/pantsbuild/pants/issues/new/choose.
203
            """
204
        ),
205
    )
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