aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/internal/api_implementation.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/internal/api_implementation.py')
-rwxr-xr-xpython/google/protobuf/internal/api_implementation.py74
1 files changed, 70 insertions, 4 deletions
diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py
index ffcf7511..ab9e7812 100755
--- a/python/google/protobuf/internal/api_implementation.py
+++ b/python/google/protobuf/internal/api_implementation.py
@@ -32,6 +32,7 @@
"""
import os
+import warnings
import sys
try:
@@ -60,10 +61,18 @@ if _api_version < 0: # Still unspecified?
del _use_fast_cpp_protos
_api_version = 2
except ImportError:
- if _proto_extension_modules_exist_in_build:
- if sys.version_info[0] >= 3: # Python 3 defaults to C++ impl v2.
- _api_version = 2
- # TODO(b/17427486): Make Python 2 default to C++ impl v2.
+ try:
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf.internal import use_pure_python
+ del use_pure_python # Avoids a pylint error and namespace pollution.
+ except ImportError:
+ # TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default;
+ # it can cause data loss if you have any Python-only extensions to any
+ # message passed back and forth with C++ code.
+ #
+ # TODO(b/17427486): Once that bug is fixed, we want to make both Python 2
+ # and Python 3 default to `_api_version = 2` (C++ implementation V2).
+ pass
_default_implementation_type = (
'python' if _api_version <= 0 else 'cpp')
@@ -78,6 +87,11 @@ _implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
if _implementation_type != 'python':
_implementation_type = 'cpp'
+if 'PyPy' in sys.version and _implementation_type == 'cpp':
+ warnings.warn('PyPy does not work yet with cpp protocol buffers. '
+ 'Falling back to the python implementation.')
+ _implementation_type = 'python'
+
# This environment variable can be used to switch between the two
# 'cpp' implementations, overriding the compile-time constants in the
# _api_implementation module. Right now only '2' is supported. Any other
@@ -94,6 +108,27 @@ if _implementation_version_str != '2':
_implementation_version = int(_implementation_version_str)
+# Detect if serialization should be deterministic by default
+try:
+ # The presence of this module in a build allows the proto implementation to
+ # be upgraded merely via build deps.
+ #
+ # NOTE: Merely importing this automatically enables deterministic proto
+ # serialization for C++ code, but we still need to export it as a boolean so
+ # that we can do the same for `_implementation_type == 'python'`.
+ #
+ # NOTE2: It is possible for C++ code to enable deterministic serialization by
+ # default _without_ affecting Python code, if the C++ implementation is not in
+ # use by this module. That is intended behavior, so we don't actually expose
+ # this boolean outside of this module.
+ #
+ # pylint: disable=g-import-not-at-top,unused-import
+ from google.protobuf import enable_deterministic_proto_serialization
+ _python_deterministic_proto_serialization = True
+except ImportError:
+ _python_deterministic_proto_serialization = False
+
+
# Usage of this function is discouraged. Clients shouldn't care which
# implementation of the API is in use. Note that there is no guarantee
# that differences between APIs will be maintained.
@@ -105,3 +140,34 @@ def Type():
# See comment on 'Type' above.
def Version():
return _implementation_version
+
+
+# For internal use only
+def IsPythonDefaultSerializationDeterministic():
+ return _python_deterministic_proto_serialization
+
+# DO NOT USE: For migration and testing only. Will be removed when Proto3
+# defaults to preserve unknowns.
+if _implementation_type == 'cpp':
+ try:
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf.pyext import _message
+
+ def GetPythonProto3PreserveUnknownsDefault():
+ return _message.GetPythonProto3PreserveUnknownsDefault()
+
+ def SetPythonProto3PreserveUnknownsDefault(preserve):
+ _message.SetPythonProto3PreserveUnknownsDefault(preserve)
+ except ImportError:
+ # Unrecognized cpp implementation. Skipping the unknown fields APIs.
+ pass
+else:
+ _python_proto3_preserve_unknowns_default = True
+
+ def GetPythonProto3PreserveUnknownsDefault():
+ return _python_proto3_preserve_unknowns_default
+
+ def SetPythonProto3PreserveUnknownsDefault(preserve):
+ global _python_proto3_preserve_unknowns_default
+ _python_proto3_preserve_unknowns_default = preserve
+