• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Protobuf Python runtime
2#
3# See also code generation logic under /src/google/protobuf/compiler/python.
4#
5# Most users should depend upon public aliases in the root:
6#   //:protobuf_python
7#   //:well_known_types_py_pb2
8
9load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
10load("@rules_python//python:defs.bzl", "py_library")
11load("//:protobuf.bzl", "internal_py_proto_library")
12load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain")
13load("//build_defs:arch_tests.bzl", "aarch64_test", "x86_64_test")
14load("//build_defs:cpp_opts.bzl", "COPTS")
15load("//conformance:defs.bzl", "conformance_test")
16load("//editions:defaults.bzl", "compile_edition_defaults", "embed_edition_defaults")
17load(":internal.bzl", "internal_copy_files", "internal_py_test")
18
19def build_targets(name):
20    """
21    Declares the build targets of the //python package.
22
23    Args:
24      name: unused.
25    """
26    py_library(
27        name = "protobuf_python",
28        data = select({
29            "//conditions:default": [],
30            ":use_fast_cpp_protos": [
31                ":google/protobuf/internal/_api_implementation.so",
32                ":google/protobuf/pyext/_message.so",
33            ],
34        }),
35        visibility = ["//:__pkg__"],
36        deps = [
37            ":python_srcs",
38            ":well_known_types_py_pb2",
39        ],
40    )
41
42    native.config_setting(
43        name = "use_fast_cpp_protos",
44        values = {
45            "define": "use_fast_cpp_protos=true",
46        },
47    )
48
49    internal_py_proto_library(
50        name = "well_known_types_py_pb2",
51        srcs = [":copied_wkt_proto_files"],
52        include = ".",
53        default_runtime = "",
54        protoc = "//:protoc",
55        srcs_version = "PY2AND3",
56        visibility = [
57            "//:__pkg__",
58            "//editions:__pkg__",
59            "//upb:__subpackages__",
60        ],
61    )
62
63    internal_copy_files(
64        name = "copied_wkt_proto_files",
65        srcs = [
66            "//:well_known_type_protos",
67            "//src/google/protobuf:descriptor_proto_srcs",
68            "//src/google/protobuf/compiler:plugin.proto",
69        ],
70        strip_prefix = "src",
71    )
72
73    native.cc_binary(
74        name = "google/protobuf/internal/_api_implementation.so",
75        srcs = ["google/protobuf/internal/api_implementation.cc"],
76        copts = COPTS + [
77            "-DPYTHON_PROTO2_CPP_IMPL_V2",
78        ],
79        linkshared = 1,
80        linkstatic = 1,
81        tags = [
82            # Exclude this target from wildcard expansion (//...) because it may
83            # not even be buildable. It will be built if it is needed according
84            # to :use_fast_cpp_protos.
85            # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
86            "manual",
87        ],
88        deps = select({
89            "//conditions:default": [],
90            ":use_fast_cpp_protos": ["@system_python//:python_headers"],
91        }),
92    )
93
94    native.config_setting(
95        name = "allow_oversize_protos",
96        values = {
97            "define": "allow_oversize_protos=true",
98        },
99    )
100
101    native.cc_binary(
102        name = "google/protobuf/pyext/_message.so",
103        srcs = native.glob([
104            "google/protobuf/pyext/*.cc",
105            "google/protobuf/pyext/*.h",
106        ]),
107        copts = COPTS + [
108            "-DGOOGLE_PROTOBUF_HAS_ONEOF=1",
109        ] + select({
110            "//conditions:default": [],
111            ":allow_oversize_protos": ["-DPROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS=1"],
112        }),
113        includes = ["."],
114        linkshared = 1,
115        linkstatic = 1,
116        tags = [
117            # Exclude this target from wildcard expansion (//...) because it may
118            # not even be buildable. It will be built if it is needed according
119            # to :use_fast_cpp_protos.
120            # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
121            "manual",
122        ],
123        deps = [
124            ":proto_api",
125            "//src/google/protobuf",
126            "//src/google/protobuf:port",
127            "//src/google/protobuf:protobuf_lite",
128            "//src/google/protobuf/io",
129            "//src/google/protobuf/io:tokenizer",
130            "//src/google/protobuf/stubs:lite",
131            "//src/google/protobuf/util:differencer",
132            "@com_google_absl//absl/container:flat_hash_map",
133            "@com_google_absl//absl/log:absl_check",
134            "@com_google_absl//absl/log:absl_log",
135            "@com_google_absl//absl/status",
136            "@com_google_absl//absl/strings",
137        ] + select({
138            "//conditions:default": [],
139            ":use_fast_cpp_protos": ["@system_python//:python_headers"],
140        }),
141    )
142
143    aarch64_test(
144        name = "aarch64_test",
145        bazel_binaries = [
146            "google/protobuf/internal/_api_implementation.so",
147            "google/protobuf/pyext/_message.so",
148        ],
149    )
150
151    x86_64_test(
152        name = "x86_64_test",
153        bazel_binaries = [
154            "google/protobuf/internal/_api_implementation.so",
155            "google/protobuf/pyext/_message.so",
156        ],
157    )
158
159    compile_edition_defaults(
160        name = "python_edition_defaults",
161        srcs = ["//:descriptor_proto"],
162        maximum_edition = "2023",
163        minimum_edition = "PROTO2",
164    )
165
166    embed_edition_defaults(
167        name = "embedded_python_edition_defaults_generate",
168        defaults = "python_edition_defaults",
169        output = "google/protobuf/internal/python_edition_defaults.py",
170        placeholder = "DEFAULTS_VALUE",
171        template = "google/protobuf/internal/python_edition_defaults.py.template",
172    )
173
174    native.filegroup(
175        name = "python_src_files",
176        srcs = native.glob(
177            [
178                "google/protobuf/**/*.py",
179            ],
180            exclude = [
181                "google/protobuf/internal/*_test.py",
182                "google/protobuf/internal/test_util.py",
183                "google/protobuf/internal/import_test_package/__init__.py",
184            ],
185        ) + ["google/protobuf/internal/python_edition_defaults.py"],
186    )
187
188    py_library(
189        name = "python_srcs",
190        srcs = [":python_src_files"],
191        imports = ["python"],
192        srcs_version = "PY2AND3",
193        visibility = [
194            "//:__pkg__",
195            "//upb:__subpackages__",
196        ],
197    )
198
199    py_library(
200        name = "python_test_srcs",
201        srcs = native.glob([
202            "google/protobuf/internal/*_test.py",
203        ]) + [
204            "google/protobuf/internal/import_test_package/__init__.py",
205            "google/protobuf/internal/test_util.py",
206            "//python/google/protobuf/internal/numpy:__init__.py",
207            "//python/google/protobuf/internal/numpy:numpy_test.py",
208        ],
209        imports = ["python"],
210        srcs_version = "PY3",
211        visibility = [
212            "//:__pkg__",
213            "//upb:__subpackages__",
214        ],
215    )
216
217    ################################################################################
218    # Tests
219    ################################################################################
220
221    internal_copy_files(
222        name = "copied_test_proto_files",
223        testonly = 1,
224        srcs = [
225            "//:test_proto_srcs",
226            "//:test_proto_editions_srcs",
227            "//src/google/protobuf/util:test_proto_srcs",
228        ],
229        strip_prefix = "src",
230    )
231
232    internal_copy_files(
233        name = "copied_conformance_test_files",
234        testonly = 1,
235        srcs = [
236            "//src/google/protobuf:test_messages_proto2.proto",
237            "//src/google/protobuf:test_messages_proto3.proto",
238        ],
239        strip_prefix = "src",
240    )
241
242    internal_copy_files(
243        name = "copied_test_dependency_proto_files",
244        srcs = [
245            "//src/google/protobuf:cpp_features_proto_srcs",
246        ],
247        strip_prefix = "src",
248    )
249
250    internal_py_proto_library(
251        name = "test_dependency_proto_py_pb2",
252        srcs = [":copied_test_dependency_proto_files"],
253        include = ".",
254        default_runtime = "",
255        protoc = "//:protoc",
256        srcs_version = "PY2AND3",
257        visibility = [
258            "//:__pkg__",
259            "//upb:__subpackages__",
260        ],
261        deps = [":well_known_types_py_pb2"],
262    )
263
264    internal_py_proto_library(
265        name = "python_common_test_protos",
266        testonly = 1,
267        srcs = [":copied_test_proto_files"],
268        include = ".",
269        default_runtime = "",
270        protoc = "//:protoc",
271        srcs_version = "PY2AND3",
272        visibility = ["//:__pkg__"],
273        deps = [":well_known_types_py_pb2", ":test_dependency_proto_py_pb2"],
274    )
275
276    internal_py_proto_library(
277        name = "python_specific_test_protos",
278        testonly = 1,
279        srcs = native.glob([
280            "google/protobuf/internal/*.proto",
281            "google/protobuf/internal/import_test_package/*.proto",
282        ]),
283        include = ".",
284        default_runtime = ":protobuf_python",
285        protoc = "//:protoc",
286        srcs_version = "PY2AND3",
287        visibility = ["//:__pkg__"],
288        deps = [":python_common_test_protos"],
289    )
290
291    internal_py_proto_library(
292        name = "conformance_test_py_proto",
293        testonly = 1,
294        srcs = [":copied_conformance_test_files"],
295        include = ".",
296        default_runtime = "//:protobuf_python",
297        protoc = "//:protoc",
298        visibility = [
299            "//conformance:__pkg__",
300            "//python:__subpackages__",
301        ],
302        deps = [":well_known_types_py_pb2"],
303    )
304
305    py_library(
306        name = "python_test_lib",
307        testonly = 1,
308        srcs = [
309            "google/protobuf/internal/import_test_package/__init__.py",
310            "google/protobuf/internal/test_util.py",
311        ],
312        imports = ["python"],
313        srcs_version = "PY2AND3",
314        visibility = ["//python:__subpackages__"],
315        deps = [
316            ":protobuf_python",
317            ":python_common_test_protos",
318            ":python_specific_test_protos",
319        ],
320    )
321
322    internal_py_test(
323        name = "descriptor_database_test",
324        srcs = ["google/protobuf/internal/descriptor_database_test.py"],
325    )
326
327    internal_py_test(
328        name = "descriptor_pool_test",
329        srcs = ["google/protobuf/internal/descriptor_pool_test.py"],
330    )
331
332    internal_py_test(
333        name = "descriptor_test",
334        srcs = ["google/protobuf/internal/descriptor_test.py"],
335    )
336
337    internal_py_test(
338        name = "field_mask_test",
339        srcs = ["google/protobuf/internal/field_mask_test.py"],
340    )
341
342    internal_py_test(
343        name = "generator_test",
344        srcs = ["google/protobuf/internal/generator_test.py"],
345    )
346
347    internal_py_test(
348        name = "import_test",
349        srcs = ["google/protobuf/internal/import_test.py"],
350    )
351
352    internal_py_test(
353        name = "json_format_test",
354        srcs = ["google/protobuf/internal/json_format_test.py"],
355    )
356
357    internal_py_test(
358        name = "keywords_test",
359        srcs = ["google/protobuf/internal/keywords_test.py"],
360    )
361
362    internal_py_test(
363        name = "message_factory_test",
364        srcs = ["google/protobuf/internal/message_factory_test.py"],
365    )
366
367    internal_py_test(
368        name = "message_test",
369        srcs = ["google/protobuf/internal/message_test.py"],
370        data = ["//src/google/protobuf:testdata"],
371    )
372
373    internal_py_test(
374        name = "proto_builder_test",
375        srcs = ["google/protobuf/internal/proto_builder_test.py"],
376    )
377
378    internal_py_test(
379        name = "reflection_test",
380        srcs = ["google/protobuf/internal/reflection_test.py"],
381    )
382
383    internal_py_test(
384        name = "service_reflection_test",
385        srcs = ["google/protobuf/internal/service_reflection_test.py"],
386    )
387
388    internal_py_test(
389        name = "symbol_database_test",
390        srcs = ["google/protobuf/internal/symbol_database_test.py"],
391    )
392
393    internal_py_test(
394        name = "text_encoding_test",
395        srcs = ["google/protobuf/internal/text_encoding_test.py"],
396    )
397
398    internal_py_test(
399        name = "text_format_test",
400        srcs = ["google/protobuf/internal/text_format_test.py"],
401        data = ["//src/google/protobuf:testdata"],
402    )
403
404    internal_py_test(
405        name = "unknown_fields_test",
406        srcs = ["google/protobuf/internal/unknown_fields_test.py"],
407    )
408
409    internal_py_test(
410        name = "well_known_types_test",
411        srcs = ["google/protobuf/internal/well_known_types_test.py"],
412    )
413
414    internal_py_test(
415        name = "decoder_test",
416        srcs = ["google/protobuf/internal/decoder_test.py"],
417    )
418
419    internal_py_test(
420        name = "wire_format_test",
421        srcs = ["google/protobuf/internal/wire_format_test.py"],
422    )
423
424    internal_py_test(
425        name = "proto_test",
426        srcs = ["google/protobuf/internal/proto_test.py"],
427    )
428
429    internal_py_test(
430        name = "proto_json_test",
431        srcs = ["google/protobuf/internal/proto_json_test.py"],
432    )
433
434    native.cc_library(
435        name = "proto_api",
436        hdrs = ["google/protobuf/proto_api.h"],
437        visibility = ["//visibility:public"],
438        deps = [
439            "@system_python//:python_headers",
440        ],
441    )
442
443    internal_py_test(
444        name = "python_version_test",
445        srcs = ["python_version_test.py"],
446    )
447
448    conformance_test(
449        name = "conformance_test",
450        env = {"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": "python"},
451        failure_list = "//conformance:failure_list_python.txt",
452        target_compatible_with = select({
453            "@system_python//:none": ["@platforms//:incompatible"],
454            ":use_fast_cpp_protos": ["@platforms//:incompatible"],
455            "//conditions:default": [],
456        }),
457        maximum_edition = "2023",
458        testee = "//conformance:conformance_python",
459        text_format_failure_list = "//conformance:text_format_failure_list_python.txt",
460    )
461
462    # Note: this requires --define=use_fast_cpp_protos=true
463    conformance_test(
464        name = "conformance_test_cpp",
465        env = {"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": "cpp"},
466        failure_list = "//conformance:failure_list_python.txt",
467        target_compatible_with = select({
468            "@system_python//:none": ["@platforms//:incompatible"],
469            ":use_fast_cpp_protos": [],
470            "//conditions:default": ["@platforms//:incompatible"],
471        }),
472        maximum_edition = "2023",
473        testee = "//conformance:conformance_python",
474        text_format_failure_list = "//conformance:text_format_failure_list_python_cpp.txt",
475    )
476
477    conformance_test(
478        name = "conformance_test_upb",
479        env = {"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": "upb"},
480        failure_list = "//conformance:failure_list_python_upb.txt",
481        target_compatible_with = select({
482            "@system_python//:none": ["@platforms//:incompatible"],
483            ":use_fast_cpp_protos": ["@platforms//:incompatible"],
484            "//conditions:default": [],
485        }),
486        maximum_edition = "2023",
487        testee = "//conformance:conformance_python",
488        text_format_failure_list = "//conformance:text_format_failure_list_python_upb.txt",
489    )
490
491    ################################################################################
492    # Distribution files
493    ################################################################################
494
495    pkg_files(
496        name = "python_source_files",
497        srcs = [
498            ":python_src_files",
499            "README.md",
500            "google/__init__.py",
501        ],
502        strip_prefix = "",
503        visibility = ["//python/dist:__pkg__"],
504    )
505
506    pkg_files(
507        name = "dist_files",
508        srcs = native.glob([
509            "google/**/*.proto",
510            "google/**/*.py",
511            "google/protobuf/internal/*.cc",
512            "google/protobuf/pyext/*.cc",
513            "google/protobuf/pyext/*.h",
514        ]) + [
515            "BUILD.bazel",
516            "MANIFEST.in",
517            "README.md",
518            "build_targets.bzl",
519            "google/protobuf/proto_api.h",
520            "google/protobuf/pyext/README",
521            "google/protobuf/python_protobuf.h",
522            "internal.bzl",
523            "python_version_test.py",
524        ],
525        strip_prefix = strip_prefix.from_root(""),
526        visibility = ["//pkg:__pkg__"],
527    )
528
529    proto_lang_toolchain(
530        name = "python_toolchain",
531        command_line = "--python_out=%s",
532        progress_message = "Generating Python proto_library %{label}",
533        runtime = ":protobuf_python",
534        # NOTE: This isn't *actually* public. It's an implicit dependency of py_proto_library,
535        # so must be public so user usages of the rule can reference it.
536        visibility = ["//visibility:public"],
537    )
538