Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/protobuf/internal/api_implementation.py: 54%
69 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +0000
1# Protocol Buffers - Google's data interchange format
2# Copyright 2008 Google Inc. All rights reserved.
3#
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file or at
6# https://developers.google.com/open-source/licenses/bsd
8"""Determine which implementation of the protobuf API is used in this process.
9"""
11import importlib
12import os
13import sys
14import warnings
17def _ApiVersionToImplementationType(api_version):
18 if api_version == 2:
19 return 'cpp'
20 if api_version == 1:
21 raise ValueError('api_version=1 is no longer supported.')
22 if api_version == 0:
23 return 'python'
24 return None
27_implementation_type = None
28try:
29 # pylint: disable=g-import-not-at-top
30 from google.protobuf.internal import _api_implementation
31 # The compile-time constants in the _api_implementation module can be used to
32 # switch to a certain implementation of the Python API at build time.
33 _implementation_type = _ApiVersionToImplementationType(
34 _api_implementation.api_version)
35except ImportError:
36 pass # Unspecified by compiler flags.
39def _CanImport(mod_name):
40 try:
41 mod = importlib.import_module(mod_name)
42 # Work around a known issue in the classic bootstrap .par import hook.
43 if not mod:
44 raise ImportError(mod_name + ' import succeeded but was None')
45 return True
46 except ImportError:
47 return False
50if _implementation_type is None:
51 if _CanImport('google._upb._message'):
52 _implementation_type = 'upb'
53 elif _CanImport('google.protobuf.pyext._message'):
54 _implementation_type = 'cpp'
55 else:
56 _implementation_type = 'python'
59# This environment variable can be used to switch to a certain implementation
60# of the Python API, overriding the compile-time constants in the
61# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are
62# valid values. Any other value will raise error.
63_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
64 _implementation_type)
66if _implementation_type not in ('python', 'cpp', 'upb'):
67 raise ValueError('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION {0} is not '
68 'supported. Please set to \'python\', \'cpp\' or '
69 '\'upb\'.'.format(_implementation_type))
71if 'PyPy' in sys.version and _implementation_type == 'cpp':
72 warnings.warn('PyPy does not work yet with cpp protocol buffers. '
73 'Falling back to the python implementation.')
74 _implementation_type = 'python'
76_c_module = None
78if _implementation_type == 'cpp':
79 try:
80 # pylint: disable=g-import-not-at-top
81 from google.protobuf.pyext import _message
82 sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message
83 _c_module = _message
84 del _message
85 except ImportError:
86 # TODO: fail back to python
87 warnings.warn(
88 'Selected implementation cpp is not available.')
89 pass
91if _implementation_type == 'upb':
92 try:
93 # pylint: disable=g-import-not-at-top
94 from google._upb import _message
95 _c_module = _message
96 del _message
97 except ImportError:
98 warnings.warn('Selected implementation upb is not available. '
99 'Falling back to the python implementation.')
100 _implementation_type = 'python'
101 pass
103# Detect if serialization should be deterministic by default
104try:
105 # The presence of this module in a build allows the proto implementation to
106 # be upgraded merely via build deps.
107 #
108 # NOTE: Merely importing this automatically enables deterministic proto
109 # serialization for C++ code, but we still need to export it as a boolean so
110 # that we can do the same for `_implementation_type == 'python'`.
111 #
112 # NOTE2: It is possible for C++ code to enable deterministic serialization by
113 # default _without_ affecting Python code, if the C++ implementation is not in
114 # use by this module. That is intended behavior, so we don't actually expose
115 # this boolean outside of this module.
116 #
117 # pylint: disable=g-import-not-at-top,unused-import
118 from google.protobuf import enable_deterministic_proto_serialization
119 _python_deterministic_proto_serialization = True
120except ImportError:
121 _python_deterministic_proto_serialization = False
124# Usage of this function is discouraged. Clients shouldn't care which
125# implementation of the API is in use. Note that there is no guarantee
126# that differences between APIs will be maintained.
127# Please don't use this function if possible.
128def Type():
129 return _implementation_type
132# See comment on 'Type' above.
133# TODO: Remove the API, it returns a constant. b/228102101
134def Version():
135 return 2
138# For internal use only
139def IsPythonDefaultSerializationDeterministic():
140 return _python_deterministic_proto_serialization