• 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/google_cloud_function/python/target_types.py
1
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

UNCOV
4
import re
×
UNCOV
5
from enum import Enum
×
UNCOV
6
from re import Match
×
UNCOV
7
from typing import cast
×
8

UNCOV
9
from pants.backend.python.target_types import PexCompletePlatformsField, PythonResolveField
×
UNCOV
10
from pants.backend.python.util_rules.faas import (
×
11
    FaaSArchitecture,
12
    PythonFaaSCompletePlatforms,
13
    PythonFaaSDependencies,
14
    PythonFaaSHandlerField,
15
    PythonFaaSKnownRuntime,
16
    PythonFaaSLayoutField,
17
    PythonFaaSPex3VenvCreateExtraArgsField,
18
    PythonFaaSPexBuildExtraArgs,
19
    PythonFaaSRuntimeField,
20
)
UNCOV
21
from pants.backend.python.util_rules.faas import rules as faas_rules
×
UNCOV
22
from pants.core.environments.target_types import EnvironmentField
×
UNCOV
23
from pants.core.goals.package import OutputPathField
×
UNCOV
24
from pants.engine.addresses import Address
×
UNCOV
25
from pants.engine.rules import collect_rules
×
UNCOV
26
from pants.engine.target import COMMON_TARGET_FIELDS, InvalidFieldException, StringField, Target
×
UNCOV
27
from pants.util.docutil import doc_url
×
UNCOV
28
from pants.util.strutil import help_text, softwrap
×
29

30

UNCOV
31
class PythonGoogleCloudFunctionHandlerField(PythonFaaSHandlerField):
×
32
    # GCP requires "Your main file must be named main.py"
33
    # https://cloud.google.com/functions/docs/writing#directory-structure-python
UNCOV
34
    reexported_handler_module = "main"
×
35

UNCOV
36
    help = help_text(
×
37
        f"""
38
        Entry point to the Google Cloud Function handler.
39

40
        {PythonFaaSHandlerField.help}
41

42
        This is re-exported at `{reexported_handler_module}.handler` in the resulting package to
43
        used as the configured handler of the Google Cloud Function in GCP.  It can also be accessed
44
        under its source-root-relative module path, for example: `path.to.module.handler_func`.
45
        """
46
    )
47

48

UNCOV
49
PYTHON_RUNTIME_REGEX = r"^python(?P<major>\d)(?P<minor>\d+)$"
×
50

51

UNCOV
52
class PythonGoogleCloudFunctionRuntimes(Enum):
×
UNCOV
53
    PYTHON_37 = "python37"
×
UNCOV
54
    PYTHON_38 = "python38"
×
UNCOV
55
    PYTHON_39 = "python39"
×
UNCOV
56
    PYTHON_310 = "python310"
×
UNCOV
57
    PYTHON_311 = "python311"
×
UNCOV
58
    PYTHON_312 = "python312"
×
59

UNCOV
60
    def to_interpreter_version(self) -> tuple[int, int]:
×
61
        """Returns the Python version implied by the runtime, as (major, minor)."""
UNCOV
62
        mo = cast(Match, re.match(PYTHON_RUNTIME_REGEX, self.value))
×
UNCOV
63
        return int(mo.group("major")), int(mo.group("minor"))
×
64

65

UNCOV
66
class PythonGoogleCloudFunctionRuntime(PythonFaaSRuntimeField):
×
UNCOV
67
    DOCKER_RUNTIME_MAPPING = {
×
68
        PythonGoogleCloudFunctionRuntimes.PYTHON_37: (
69
            "us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python37",
70
            "python37_20240728_3_7_17_RC00",
71
        ),
72
        PythonGoogleCloudFunctionRuntimes.PYTHON_38: (
73
            "us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python38",
74
            "python38_20240728_3_8_19_RC00",
75
        ),
76
        PythonGoogleCloudFunctionRuntimes.PYTHON_39: (
77
            "us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python39",
78
            "python39_20240728_3_9_19_RC00",
79
        ),
80
        PythonGoogleCloudFunctionRuntimes.PYTHON_310: (
81
            "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python310",
82
            "python310_20240728_3_10_14_RC00",
83
        ),
84
        PythonGoogleCloudFunctionRuntimes.PYTHON_311: (
85
            "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python311",
86
            "python311_20240728_3_11_9_RC00",
87
        ),
88
        PythonGoogleCloudFunctionRuntimes.PYTHON_312: (
89
            "us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python312",
90
            "python312_20240728_3_12_4_RC00",
91
        ),
92
    }
93

UNCOV
94
    valid_choices = PythonGoogleCloudFunctionRuntimes
×
UNCOV
95
    help = help_text(
×
96
        """
97
        The identifier of the Google Cloud Function runtime to target (pythonXY). See
98
        https://cloud.google.com/functions/docs/concepts/python-runtime.
99

100
        In general you'll want to define either a `runtime` or one `complete_platforms` but not
101
        both. Specifying a `runtime` is simpler, but less accurate. If you have issues either
102
        packaging the Google Cloud Function PEX or running it as a deployed Google Cloud Function,
103
        you should try using `complete_platforms` instead.
104
        """
105
    )
106

UNCOV
107
    known_runtimes = tuple(
×
108
        PythonFaaSKnownRuntime(
109
            runtime.value,
110
            *runtime.to_interpreter_version(),
111
            docker_repo,
112
            docker_tag,
113
            FaaSArchitecture.X86_64,
114
        )
115
        for runtime, (docker_repo, docker_tag) in DOCKER_RUNTIME_MAPPING.items()
116
    )
117

UNCOV
118
    @classmethod
×
UNCOV
119
    def compute_value(cls, raw_value: str | None, address: Address) -> str | None:
×
UNCOV
120
        value = super().compute_value(raw_value, address)
×
UNCOV
121
        if value is None:
×
122
            return None
×
UNCOV
123
        if not re.match(PYTHON_RUNTIME_REGEX, value):
×
124
            raise InvalidFieldException(
×
125
                f"The `{cls.alias}` field in target at {address} must be of the form pythonXY, "
126
                f"but was {value}."
127
            )
UNCOV
128
        return value
×
129

UNCOV
130
    def to_interpreter_version(self) -> tuple[int, int] | None:
×
131
        """Returns the Python version implied by the runtime, as (major, minor)."""
UNCOV
132
        if self.value is None:
×
133
            return None
×
UNCOV
134
        mo = cast(Match, re.match(PYTHON_RUNTIME_REGEX, self.value))
×
UNCOV
135
        return int(mo.group("major")), int(mo.group("minor"))
×
136

UNCOV
137
    @classmethod
×
UNCOV
138
    def from_interpreter_version(cls, py_major: int, py_minor) -> str:
×
139
        return f"python{py_major}{py_minor}"
×
140

141

UNCOV
142
class GoogleCloudFunctionTypes(Enum):
×
UNCOV
143
    EVENT = "event"
×
UNCOV
144
    HTTP = "http"
×
145

146

UNCOV
147
class PythonGoogleCloudFunctionType(StringField):
×
UNCOV
148
    alias = "type"
×
UNCOV
149
    required = True
×
UNCOV
150
    valid_choices = GoogleCloudFunctionTypes
×
UNCOV
151
    help = help_text(
×
152
        """
153
        The trigger type of the cloud function. Can either be `'event'` or `'http'`.
154
        See https://cloud.google.com/functions/docs/concepts/python-runtime for reference to
155
        `--trigger-http`.
156
        """
157
    )
158

159

UNCOV
160
class PythonGoogleCloudFunction(Target):
×
UNCOV
161
    alias = "python_google_cloud_function"
×
UNCOV
162
    core_fields = (
×
163
        *COMMON_TARGET_FIELDS,
164
        OutputPathField,
165
        PythonFaaSDependencies,
166
        PythonGoogleCloudFunctionHandlerField,
167
        PythonGoogleCloudFunctionRuntime,
168
        PythonFaaSCompletePlatforms,
169
        PythonGoogleCloudFunctionType,
170
        PythonFaaSPex3VenvCreateExtraArgsField,
171
        PythonFaaSPexBuildExtraArgs,
172
        PythonFaaSLayoutField,
173
        PythonResolveField,
174
        EnvironmentField,
175
    )
UNCOV
176
    help = help_text(
×
177
        f"""
178
        A self-contained Python function suitable for uploading to Google Cloud Function.
179

180
        See {doc_url("docs/python/integrations/google-cloud-functions")}.
181
        """
182
    )
183

UNCOV
184
    def validate(self) -> None:
×
185
        has_runtime = self[PythonGoogleCloudFunctionRuntime].value is not None
×
186
        has_complete_platforms = self[PexCompletePlatformsField].value is not None
×
187

188
        runtime_alias = self[PythonGoogleCloudFunctionRuntime].alias
×
189
        complete_platforms_alias = self[PexCompletePlatformsField].alias
×
190

191
        if has_runtime and has_complete_platforms:
×
192
            raise ValueError(
×
193
                softwrap(
194
                    f"""
195
                    The `{complete_platforms_alias}` takes precedence over the `{runtime_alias}` field, if
196
                    it is set. Remove the `{runtime_alias}` field to only use the `{complete_platforms_alias}`
197
                    value, or remove the `{complete_platforms_alias}` field to use the default platform
198
                    implied by `{runtime_alias}`.
199
                    """
200
                ),
201
            )
202

203

UNCOV
204
def rules():
×
UNCOV
205
    return (
×
206
        *collect_rules(),
207
        *faas_rules(),
208
    )
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