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

pantsbuild / pants / 21883587496

10 Feb 2026 09:45PM UTC coverage: 80.342% (-0.008%) from 80.35%
21883587496

Pull #23092

github

web-flow
Merge c4a3852cf into 9a67b81d3
Pull Request #23092: Support for a `# pants: infer-dep(...)` pragma.

9 of 11 new or added lines in 3 files covered. (81.82%)

9 existing lines in 2 files now uncovered.

78765 of 98037 relevant lines covered (80.34%)

3.36 hits per line

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

80.49
/src/python/pants/backend/python/framework/django/dependency_inference_test.py
1
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
1✔
5

6
from textwrap import dedent
1✔
7

8
import pytest
1✔
9

10
from pants.backend.python.dependency_inference import parse_python_dependencies
1✔
11
from pants.backend.python.dependency_inference.rules import (
1✔
12
    PythonImportDependenciesInferenceFieldSet,
13
)
14
from pants.backend.python.dependency_inference.rules import rules as core_rules
1✔
15
from pants.backend.python.framework.django import dependency_inference, detect_apps
1✔
16
from pants.backend.python.target_types import PythonSourceTarget
1✔
17
from pants.backend.python.util_rules import pex
1✔
18
from pants.core.util_rules import stripped_source_files
1✔
19
from pants.engine.addresses import Address
1✔
20
from pants.engine.rules import QueryRule
1✔
21
from pants.engine.target import InferredDependencies
1✔
22
from pants.testutil.python_interpreter_selection import (
1✔
23
    skip_unless_python38_present,
24
    skip_unless_python39_present,
25
)
26
from pants.testutil.rule_runner import RuleRunner
1✔
27

28

29
@pytest.fixture
1✔
30
def rule_runner() -> RuleRunner:
1✔
31
    rule_runner = RuleRunner(
1✔
32
        rules=[
33
            *parse_python_dependencies.rules(),
34
            *stripped_source_files.rules(),
35
            *pex.rules(),
36
            *dependency_inference.rules(),
37
            *detect_apps.rules(),
38
            *core_rules(),
39
            QueryRule(InferredDependencies, [dependency_inference.InferDjangoDependencies]),
40
        ],
41
        target_types=[PythonSourceTarget],
42
    )
43
    rule_runner.set_options([], env_inherit={"PATH", "PYENV_ROOT", "HOME"})
1✔
44
    return rule_runner
1✔
45

46

47
def files(constraints: str) -> dict[str, str]:
1✔
48
    return {
1✔
49
        "BUILD": "python_source(name='t', source='path/to/app0/migrations/0001_initial.py')",
50
        "path/to/app0/migrations/__init__.py": "",
51
        "path/to/app0/migrations/0001_initial.py": dedent(
52
            """\
53
            class Migration(migrations.Migration):
54
                dependencies = [
55
                ("app1", "0012_some_migration"),
56
                ("app2_label", "0042_another_migration"),
57
                ]
58

59
                operations = []
60
            """
61
        ),
62
        "path/to/app1/BUILD": dedent(
63
            f"""\
64
                python_source(
65
                  name="app1",
66
                  source="apps.py",
67
                  interpreter_constraints=['{constraints}'],
68
                )
69
                python_source(
70
                  name="initpy",
71
                  source="__init__.py",
72
                )
73
                """
74
        ),
75
        "path/to/app1/__init__.py": "",
76
        "path/to/app1/apps.py": dedent(
77
            """\
78
                class App1AppConfig(AppConfig):
79
                    name = "path.to.app1"
80
                    label = "app1"
81
                """
82
        ),
83
        "path/to/app1/management/commands/BUILD": dedent(
84
            """\
85
                python_source(source='do_a_thing.py')
86
                python_source(
87
                    name="initpy",
88
                    source="__init__.py",
89
                )
90
                """
91
        ),
92
        "path/to/app1/management/commands/__init__.py": "",
93
        "path/to/app1/management/commands/do_a_thing.py": "",
94
        "path/to/app1/migrations/BUILD": dedent(
95
            """\
96
                python_source(source='0012_some_migration.py')
97
                python_source(
98
                    name="initpy",
99
                    source="__init__.py",
100
                )
101
                """
102
        ),
103
        "path/to/app1/migrations/__init__.py": "",
104
        "path/to/app1/migrations/0012_some_migration.py": "",
105
        "another/path/app2/BUILD": dedent(
106
            f"""\
107
                python_source(
108
                  source="apps.py",
109
                  interpreter_constraints=['{constraints}'],
110
                )
111
                """
112
        ),
113
        "another/path/app2/__init__.py": "",
114
        "another/path/app2/apps.py": dedent(
115
            """\
116
                class App2AppConfig(AppConfig):
117
                    name = "another.path.app2"
118
                    label = "app2_label"
119
                """
120
        ),
121
        "another/path/app2/migrations/BUILD": dedent(
122
            """\
123
                python_source(source='0042_another_migration.py')
124
                python_source(
125
                    name="initpy",
126
                    source="__init__.py",
127
                )
128
                """
129
        ),
130
        "another/path/app2/migrations/__init__.py": "",
131
        "another/path/app2/migrations/0042_another_migration.py": "",
132
    }
133

134

135
def do_test_migration_dependencies(rule_runner: RuleRunner, constraints: str) -> None:
1✔
136
    rule_runner.write_files(files(constraints))
1✔
137
    tgt = rule_runner.get_target(Address("", target_name="t"))
1✔
138
    result = rule_runner.request(
1✔
139
        InferredDependencies,
140
        [
141
            dependency_inference.InferDjangoDependencies(
142
                PythonImportDependenciesInferenceFieldSet.create(tgt)
143
            )
144
        ],
145
    )
UNCOV
146
    assert set(result.include) == {
×
147
        Address("another/path/app2/migrations", target_name="migrations"),
148
        Address("path/to/app1/migrations", target_name="migrations"),
149
    }
150

151

152
def do_test_implicit_app_dependencies(rule_runner: RuleRunner, constraints: str) -> None:
1✔
UNCOV
153
    rule_runner.write_files(files(constraints))
×
UNCOV
154
    tgt = rule_runner.get_target(Address("path/to/app1", target_name="app1"))
×
UNCOV
155
    print(tgt)
×
UNCOV
156
    result = rule_runner.request(
×
157
        InferredDependencies,
158
        [
159
            dependency_inference.InferDjangoDependencies(
160
                PythonImportDependenciesInferenceFieldSet.create(tgt)
161
            )
162
        ],
163
    )
UNCOV
164
    assert set(result.include) == {
×
165
        Address("path/to/app1/migrations", target_name="migrations"),
166
        Address("path/to/app1/migrations", target_name="initpy"),
167
        Address("path/to/app1/management/commands", target_name="commands"),
168
        Address("path/to/app1/management/commands", target_name="initpy"),
169
    }
170

171

172
@skip_unless_python38_present
1✔
173
def test_works_with_python38(rule_runner: RuleRunner) -> None:
1✔
174
    do_test_migration_dependencies(rule_runner, constraints="CPython==3.8.*")
1✔
UNCOV
175
    do_test_implicit_app_dependencies(rule_runner, constraints="CPython==3.8.*")
×
176

177

178
@skip_unless_python39_present
1✔
179
def test_works_with_python39(rule_runner: RuleRunner) -> None:
1✔
180
    do_test_migration_dependencies(rule_runner, constraints="CPython==3.9.*")
1✔
UNCOV
181
    do_test_implicit_app_dependencies(rule_runner, constraints="CPython==3.9.*")
×
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