codekingpro/portable-devtools
114k
1# Protocol Buffers - Google's data interchange format2# Copyright 2008 Google Inc. All rights reserved.3#4# Use of this source code is governed by a BSD-style5# license that can be found in the LICENSE file or at6# https://developers.google.com/open-source/licenses/bsd7 8"""Determine which implementation of the protobuf API is used in this process.9"""10 11import importlib12import os13import sys14import warnings15 16_GOOGLE3_PYTHON_UPB_DEFAULT = True17 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 None27 28 29_implementation_type = None30try:31 # pylint: disable=g-import-not-at-top32 from google.protobuf.internal import _api_implementation33 # The compile-time constants in the _api_implementation module can be used to34 # 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 True48 except ImportError:49 return False50 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 implementation62# of the Python API, overriding the compile-time constants in the63# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are64# 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 = None79 80if _implementation_type == 'cpp':81 try:82 # pylint: disable=g-import-not-at-top83 from google.protobuf.pyext import _message84 sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message85 _c_module = _message86 del _message87 except ImportError:88 # TODO: fail back to python89 warnings.warn(90 'Selected implementation cpp is not available.')91 pass92 93if _implementation_type == 'upb':94 try:95 # pylint: disable=g-import-not-at-top96 from google._upb import _message97 _c_module = _message98 del _message99 except ImportError:100 warnings.warn('Selected implementation upb is not available. '101 'Falling back to the python implementation.')102 _implementation_type = 'python'103 pass104 105# Detect if serialization should be deterministic by default106try:107 # The presence of this module in a build allows the proto implementation to108 # be upgraded merely via build deps.109 #110 # NOTE: Merely importing this automatically enables deterministic proto111 # serialization for C++ code, but we still need to export it as a boolean so112 # that we can do the same for `_implementation_type == 'python'`.113 #114 # NOTE2: It is possible for C++ code to enable deterministic serialization by115 # default _without_ affecting Python code, if the C++ implementation is not in116 # use by this module. That is intended behavior, so we don't actually expose117 # this boolean outside of this module.118 #119 # pylint: disable=g-import-not-at-top,unused-import120 from google.protobuf import enable_deterministic_proto_serialization121 _python_deterministic_proto_serialization = True122except ImportError:123 _python_deterministic_proto_serialization = False124 125 126# Usage of this function is discouraged. Clients shouldn't care which127# implementation of the API is in use. Note that there is no guarantee128# that differences between APIs will be maintained.129# Please don't use this function if possible.130def Type():131 return _implementation_type132 133 134# For internal use only135def IsPythonDefaultSerializationDeterministic():136 return _python_deterministic_proto_serialization137 