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

pantsbuild / pants / 20826906489

08 Jan 2026 06:09PM UTC coverage: 80.192% (-0.08%) from 80.274%
20826906489

Pull #22987

github

web-flow
Merge aa52dd80f into 0d471f924
Pull Request #22987: WIP DRAFT: Pex 2.77.1 tests

3 of 3 new or added lines in 1 file covered. (100.0%)

90 existing lines in 15 files now uncovered.

78714 of 98157 relevant lines covered (80.19%)

3.36 hits per line

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

94.74
/src/python/pants/backend/python/framework/django/detect_apps_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
import pytest
1✔
7

8
from pants.backend.python.dependency_inference import parse_python_dependencies
1✔
9
from pants.backend.python.framework.django import detect_apps
1✔
10
from pants.backend.python.framework.django.detect_apps import DjangoApp, DjangoApps
1✔
11
from pants.backend.python.target_types import PythonSourceTarget
1✔
12
from pants.backend.python.util_rules import pex
1✔
13
from pants.core.util_rules import stripped_source_files
1✔
14
from pants.engine.environment import EnvironmentName
1✔
15
from pants.testutil.python_interpreter_selection import (
1✔
16
    PY_38,
17
    PY_39,
18
    skip_unless_all_pythons_present,
19
    skip_unless_python37_present,
20
    skip_unless_python38_present,
21
    skip_unless_python39_present,
22
)
23
from pants.testutil.rule_runner import QueryRule, RuleRunner
1✔
24
from pants.util.frozendict import FrozenDict
1✔
25
from pants.util.strutil import softwrap
1✔
26

27

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

43

44
def assert_apps_detected(
1✔
45
    rule_runner: RuleRunner,
46
    constraints1: str,
47
    constraints2: str = "",
48
) -> None:
49
    constraints2 = constraints2 or constraints1
1✔
50
    if "3." in constraints1:
1✔
51
        py3_only = "async def i_will_parse_on_python3_not_on_python2():\n  pass"
1✔
52
    else:
53
        py3_only = ""
×
54
    rule_runner.write_files(
1✔
55
        {
56
            "path/to/app1/BUILD": softwrap(
57
                f"""\
58
                {py3_only}
59

60
                python_source(
61
                  source="apps.py",
62
                  interpreter_constraints=['{constraints1}'],
63
                )
64
                """
65
            ),
66
            "path/to/app1/apps.py": softwrap(
67
                """\
68
                class App1AppConfig(AppConfig):
69
                    name = "path.to.app1"
70
                    label = "app1"
71
                """
72
            ),
73
            "another/path/app2/BUILD": softwrap(
74
                f"""\
75
                python_source(
76
                  source="apps.py",
77
                  interpreter_constraints=['{constraints2}'],
78
                )
79
                """
80
            ),
81
            "another/path/app2/apps.py": softwrap(
82
                """\
83
                class App2AppConfig(AppConfig):
84
                    name = "another.path.app2"
85
                    label = "app2_label"
86
                """
87
            ),
88
            "some/app3/BUILD": softwrap(
89
                f"""\
90
                python_source(
91
                  source="apps.py",
92
                  interpreter_constraints=['{constraints1}'],
93
                )
94
                """
95
            ),
96
            "some/app3/apps.py": softwrap(
97
                """\
98
                class App3AppConfig(AppConfig):
99
                    name = "some.app3"
100
                    # No explicit label, should default to app3.
101
                """
102
            ),
103
        }
104
    )
105
    result = rule_runner.request(
1✔
106
        DjangoApps,
107
        [],
108
    )
UNCOV
109
    assert result == DjangoApps(
×
110
        FrozenDict(
111
            {
112
                "app1": DjangoApp("path.to.app1", "path/to/app1/apps.py"),
113
                "app2_label": DjangoApp("another.path.app2", "another/path/app2/apps.py"),
114
                "app3": DjangoApp("some.app3", "some/app3/apps.py"),
115
            }
116
        )
117
    )
118

119

120
@skip_unless_python37_present
1✔
121
def test_works_with_python37(rule_runner: RuleRunner) -> None:
1✔
122
    assert_apps_detected(rule_runner, constraints1="CPython==3.7.*")
1✔
123

124

125
@skip_unless_python38_present
1✔
126
def test_works_with_python38(rule_runner: RuleRunner) -> None:
1✔
127
    assert_apps_detected(rule_runner, constraints1="CPython==3.8.*")
1✔
128

129

130
@skip_unless_python39_present
1✔
131
def test_works_with_python39(rule_runner: RuleRunner) -> None:
1✔
132
    assert_apps_detected(rule_runner, constraints1="CPython==3.9.*")
1✔
133

134

135
@skip_unless_all_pythons_present(PY_38, PY_39)
1✔
136
def test_partitioning_by_ics(rule_runner: RuleRunner) -> None:
1✔
137
    assert_apps_detected(rule_runner, constraints1="CPython==3.8.*", constraints2="CPython==3.9.*")
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