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

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 

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 

25 

26 

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. 

37 

38 

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 

48 

49 

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' 

57 

58 

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) 

65 

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)) 

70 

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' 

75 

76_c_module = None 

77 

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 

90 

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 

102 

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 

122 

123 

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 

130 

131 

132# See comment on 'Type' above. 

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

134def Version(): 

135 return 2 

136 

137 

138# For internal use only 

139def IsPythonDefaultSerializationDeterministic(): 

140 return _python_deterministic_proto_serialization