Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/protobuf/internal/api_implementation.py: 54%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

71 statements  

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 

7 

8"""Determine which implementation of the protobuf API is used in this process. 

9""" 

10 

11import importlib 

12import os 

13import sys 

14import warnings 

15 

16_GOOGLE3_PYTHON_UPB_DEFAULT = True 

17 

18 

19def _ApiVersionToImplementationType(api_version): 

20 if api_version == 2: 

21 return 'cpp' 

22 if api_version == 1: 

23 raise ValueError('api_version=1 is no longer supported.') 

24 if api_version == 0: 

25 return 'python' 

26 return None 

27 

28 

29_implementation_type = None 

30try: 

31 # pylint: disable=g-import-not-at-top 

32 from google.protobuf.internal import _api_implementation 

33 # The compile-time constants in the _api_implementation module can be used to 

34 # switch to a certain implementation of the Python API at build time. 

35 _implementation_type = _ApiVersionToImplementationType( 

36 _api_implementation.api_version) 

37except ImportError: 

38 pass # Unspecified by compiler flags. 

39 

40 

41def _CanImport(mod_name): 

42 try: 

43 mod = importlib.import_module(mod_name) 

44 # Work around a known issue in the classic bootstrap .par import hook. 

45 if not mod: 

46 raise ImportError(mod_name + ' import succeeded but was None') 

47 return True 

48 except ImportError: 

49 return False 

50 

51 

52if _implementation_type is None: 

53 if _CanImport('google._upb._message'): 

54 _implementation_type = 'upb' 

55 elif _CanImport('google.protobuf.pyext._message'): 

56 _implementation_type = 'cpp' 

57 else: 

58 _implementation_type = 'python' 

59 

60 

61# This environment variable can be used to switch to a certain implementation 

62# of the Python API, overriding the compile-time constants in the 

63# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are 

64# valid values. Any other value will raise error. 

65_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', 

66 _implementation_type) 

67 

68if _implementation_type not in ('python', 'cpp', 'upb'): 

69 raise ValueError('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION {0} is not ' 

70 'supported. Please set to \'python\', \'cpp\' or ' 

71 '\'upb\'.'.format(_implementation_type)) 

72 

73if 'PyPy' in sys.version and _implementation_type == 'cpp': 

74 warnings.warn('PyPy does not work yet with cpp protocol buffers. ' 

75 'Falling back to the python implementation.') 

76 _implementation_type = 'python' 

77 

78_c_module = None 

79 

80if _implementation_type == 'cpp': 

81 try: 

82 # pylint: disable=g-import-not-at-top 

83 from google.protobuf.pyext import _message 

84 sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message 

85 _c_module = _message 

86 del _message 

87 except ImportError: 

88 # TODO: fail back to python 

89 warnings.warn( 

90 'Selected implementation cpp is not available.') 

91 pass 

92 

93if _implementation_type == 'upb': 

94 try: 

95 # pylint: disable=g-import-not-at-top 

96 from google._upb import _message 

97 _c_module = _message 

98 del _message 

99 except ImportError: 

100 warnings.warn('Selected implementation upb is not available. ' 

101 'Falling back to the python implementation.') 

102 _implementation_type = 'python' 

103 pass 

104 

105# Detect if serialization should be deterministic by default 

106try: 

107 # The presence of this module in a build allows the proto implementation to 

108 # be upgraded merely via build deps. 

109 # 

110 # NOTE: Merely importing this automatically enables deterministic proto 

111 # serialization for C++ code, but we still need to export it as a boolean so 

112 # that we can do the same for `_implementation_type == 'python'`. 

113 # 

114 # NOTE2: It is possible for C++ code to enable deterministic serialization by 

115 # default _without_ affecting Python code, if the C++ implementation is not in 

116 # use by this module. That is intended behavior, so we don't actually expose 

117 # this boolean outside of this module. 

118 # 

119 # pylint: disable=g-import-not-at-top,unused-import 

120 from google.protobuf import enable_deterministic_proto_serialization 

121 _python_deterministic_proto_serialization = True 

122except ImportError: 

123 _python_deterministic_proto_serialization = False 

124 

125 

126# Usage of this function is discouraged. Clients shouldn't care which 

127# implementation of the API is in use. Note that there is no guarantee 

128# that differences between APIs will be maintained. 

129# Please don't use this function if possible. 

130def Type(): 

131 return _implementation_type 

132 

133 

134# See comment on 'Type' above. 

135# TODO: Remove the API, it returns a constant. b/228102101 

136def Version(): 

137 return 2 

138 

139 

140# For internal use only 

141def IsPythonDefaultSerializationDeterministic(): 

142 return _python_deterministic_proto_serialization