Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1af7fd4

Browse files
mkruskal-googlecopybara-github
authored andcommitted
Extend gencode compatibility support back to 3.20.0
#test-continuousThis adds 2 shims for some previous breakages, and compatibility tests to avoid further accidents. This will be backported to 25.x and 29.x.PiperOrigin-RevId: 776414924
1 parent4ba9733 commit1af7fd4

File tree

6 files changed

+171
-81
lines changed

6 files changed

+171
-81
lines changed

‎.github/workflows/test_upb.yml‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,69 @@ jobs:
319319
for test in $TESTS; do
320320
python -m unittest -v $test
321321
done
322+
323+
test_python_compatibility:
324+
name:${{ inputs.continuous-prefix }} Test Python Compatibility (${{ matrix.implementation }} - ${{ matrix.version }})
325+
needs:build_wheels
326+
strategy:
327+
fail-fast:false# Don't cancel all jobs if one fails.
328+
matrix:
329+
# Test the first release of each python major version, plus some extra coverage for 3.x.y
330+
# since it predates our breaking change policies.
331+
# Major versions: 4.21.0, 5.26.0, 6.30.0
332+
version:["3.19.0", "3.20.0", "21.0", "26.0", "30.0"]
333+
implementation:["Pure", "upb"]
334+
include:
335+
# We don't support 3.19.0 anymore, so our infra should show a failure.
336+
-version:"3.19.0"
337+
fail:true
338+
runs-on:ubuntu-latest
339+
if:${{ github.event_name != 'pull_request_target' }}
340+
steps:
341+
-name:Checkout pending changes
342+
if:${{ inputs.continuous-run }}
343+
uses:protocolbuffers/protobuf-ci/checkout@v4
344+
with:
345+
ref:${{ inputs.safe-checkout }}
346+
-name:Download Wheels
347+
if:${{ inputs.continuous-run }}
348+
uses:actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16#4.1.8
349+
with:
350+
name:python-wheels
351+
path:wheels
352+
-name:Delete Binary Wheels (pure python only)
353+
if:${{ inputs.continuous-run && matrix.implementation == 'Pure' }}
354+
run:find wheels -type f | grep -v none-any | xargs rm
355+
-name:Setup Python
356+
if:${{ inputs.continuous-run }}
357+
uses:actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1# v4.7.0
358+
with:
359+
python-version:3.13
360+
-name:Setup Python venv
361+
if:${{ inputs.continuous-run }}
362+
run:|
363+
python -m pip install --upgrade pip
364+
python -m venv env
365+
source env/bin/activate
366+
echo "VIRTUAL ENV:" $VIRTUAL_ENV
367+
-name:Download Requirements
368+
if:${{ inputs.continuous-run }}
369+
uses:actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16#4.1.8
370+
with:
371+
name:requirements
372+
path:requirements
373+
-name:Install requirements
374+
if:${{ inputs.continuous-run }}
375+
run:pip install -r requirements/requirements.txt
376+
-name:Install Protobuf Wheels
377+
if:${{ inputs.continuous-run }}
378+
run:pip install -vvv --no-index --find-links wheels protobuf protobuftests
379+
-name:Make the test script executable
380+
if:${{ inputs.continuous-run }}
381+
run:chmod +x ci/python_compatibility.sh
382+
-name:Run compatibility tests
383+
if:${{ inputs.continuous-run && !matrix.fail }}
384+
run:ci/python_compatibility.sh ${{ matrix.version }}
385+
-name:Run failing compatibility tests
386+
if:${{ inputs.continuous-run && matrix.fail }}
387+
run:(! ci/python_compatibility.sh ${{ matrix.version }})

‎ci/python_compatibility.sh‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/bash
2+
3+
set -ex
4+
5+
PROTOC_VERSION=$1
6+
PROTOC_DOWNLOAD=https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/protoc-$PROTOC_VERSION-linux-x86_64.zip
7+
PY_SITE_PACKAGES=$(python -c'import site; print(site.getsitepackages()[0])')
8+
9+
rm -rf protoc-old
10+
mkdir protoc-old
11+
pushd protoc-old
12+
wget$PROTOC_DOWNLOAD
13+
unzip*.zip
14+
PROTOC=$(pwd)/bin/protoc
15+
popd
16+
17+
# protoc prior to 28.0 doesn't support inf/nan option values.
18+
sed -i's/\(inf\|nan\)/0/g' src/google/protobuf/unittest_custom_options.proto
19+
20+
bazel build //python:copied_test_proto_files //python:copied_wkt_proto_files
21+
22+
COMPAT_COPIED_PROTOS=(
23+
# Well-known types give good build coverage
24+
any
25+
api
26+
duration
27+
empty
28+
field_mask
29+
source_context
30+
struct
31+
timestamp
32+
type
33+
wrappers
34+
# These protos are used in tests of custom options handling.
35+
unittest_custom_options
36+
unittest_import
37+
)
38+
39+
forprotoin${COMPAT_COPIED_PROTOS[@]};do
40+
$PROTOC --python_out=$PY_SITE_PACKAGES \
41+
bazel-bin/python/google/protobuf/$proto.proto \
42+
-Ibazel-bin/python
43+
done
44+
45+
COMPAT_PROTOS=(
46+
# All protos without transitive dependencies on edition 2023+.
47+
descriptor_pool_test1
48+
descriptor_pool_test2
49+
factory_test1
50+
factory_test2
51+
file_options_test
52+
import_test_package/import_public
53+
import_test_package/import_public_nested
54+
import_test_package/inner
55+
import_test_package/outer
56+
message_set_extensions
57+
missing_enum_values
58+
more_extensions
59+
more_extensions_dynamic
60+
more_messages
61+
no_package
62+
packed_field_test
63+
test_bad_identifiers
64+
test_proto2
65+
test_proto3_optional
66+
)
67+
68+
forprotoin${COMPAT_PROTOS[@]};do
69+
$PROTOC --python_out=$PY_SITE_PACKAGES \
70+
python/google/protobuf/internal/$proto.proto \
71+
-Ipython
72+
done
73+
74+
# Exclude pybind11 tests because they require C++ code that doesn't ship with
75+
# our test wheels.
76+
TEST_EXCLUSIONS="_pybind11_test.py"
77+
TESTS=$(pip show -f protobuftests| grep -i _test.py| grep --invert-match$TEST_EXCLUSIONS| sed's,/,.,g'| sed -E's,.py$,,g')
78+
python -m unittest -v${TESTS[@]}

‎python/google/protobuf/descriptor.py‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,16 @@ class of the options message. The name of the class is required in case
128128
"""
129129
self._features=None
130130
self.file=file
131-
self._options=options
132-
self._loaded_options=None
131+
self._original_options=options
132+
# These two fields are duplicated as a compatibility shim for old gencode
133+
# that resets them. In 26.x (cl/580304039) we renamed _options to,
134+
# _loaded_options breaking backwards compatibility.
135+
self._options=self._loaded_options=None
133136
self._options_class_name=options_class_name
134137
self._serialized_options=serialized_options
135138

136139
# Does this descriptor have non-default options?
137-
self.has_options= (self._optionsisnotNone)or (
140+
self.has_options= (self._original_optionsisnotNone)or (
138141
self._serialized_optionsisnotNone
139142
)
140143

@@ -186,7 +189,8 @@ def _ResolveFeatures(self, edition, raw_options):
186189

187190
def_LazyLoadOptions(self):
188191
"""Lazily initializes descriptor options towards the end of the build."""
189-
ifself._loaded_options:
192+
ifself._optionsandself._loaded_options==self._options:
193+
# If neither has been reset by gencode, use the cache.
190194
return
191195

192196
# pylint: disable=g-import-not-at-top
@@ -206,12 +210,12 @@ def _LazyLoadOptions(self):
206210
descriptor_pb2.Edition.Value(edition),options_class()
207211
)
208212
with_lock:
209-
self._loaded_options=options_class()
213+
self._options=self._loaded_options=options_class()
210214
ifnotself._features:
211215
self._features=features
212216
else:
213217
ifnotself._serialized_options:
214-
options=self._options
218+
options=self._original_options
215219
else:
216220
options=_ParseOptions(options_class(),self._serialized_options)
217221

@@ -220,13 +224,13 @@ def _LazyLoadOptions(self):
220224
descriptor_pb2.Edition.Value(edition),options
221225
)
222226
with_lock:
223-
self._loaded_options=options
227+
self._options=self._loaded_options=options
224228
ifnotself._features:
225229
self._features=features
226230
ifoptions.HasField('features'):
227231
options.ClearField('features')
228232
ifnotoptions.SerializeToString():
229-
self._loaded_options=options_class()
233+
self._options=self._loaded_options=options_class()
230234
self.has_options=False
231235

232236
defGetOptions(self):
@@ -235,9 +239,10 @@ def GetOptions(self):
235239
Returns:
236240
The options set on this descriptor.
237241
"""
238-
ifnotself._loaded_options:
242+
# If either has been reset by gencode, reload options.
243+
ifnotself._optionsornotself._loaded_options:
239244
self._LazyLoadOptions()
240-
returnself._loaded_options
245+
returnself._options
241246

242247

243248
class_NestedDescriptorBase(DescriptorBase):

‎python/google/protobuf/internal/python_message.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,13 @@ def _AddPropertiesForExtensions(descriptor, cls):
829829
pool=descriptor.file.pool
830830

831831
def_AddStaticMethods(cls):
832+
833+
defRegisterExtension(_):
834+
"""no-op to keep generated code <=4.23 working with new runtimes."""
835+
# This was originally removed in 5.26 (cl/595989309).
836+
pass
837+
838+
cls.RegisterExtension=staticmethod(RegisterExtension)
832839
defFromString(s):
833840
message=cls()
834841
message.MergeFromString(s)

‎python/google/protobuf/internal/runtime_version_test.py‎

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,6 @@ def test_cross_domain_disallowed(self):
3636
gencode_domain,1,2,3,'','foo.proto'
3737
)
3838

39-
deftest_mismatched_major_disallowed(self):
40-
gencode_version_string=f'{1}.{runtime_version.MINOR}.{runtime_version.PATCH}{runtime_version.SUFFIX}'
41-
runtime_version_string=f'{runtime_version.MAJOR}.{runtime_version.MINOR}.{runtime_version.PATCH}{runtime_version.SUFFIX}'
42-
withself.assertRaisesRegex(
43-
runtime_version.VersionError,
44-
'Detected mismatched Protobuf Gencode/Runtime major versions when'
45-
f' loading foo.proto: gencode{gencode_version_string} runtime'
46-
f'{runtime_version_string}',
47-
):
48-
runtime_version.ValidateProtobufRuntimeVersion(
49-
runtime_version.DOMAIN,
50-
1,
51-
runtime_version.MINOR,
52-
runtime_version.PATCH,
53-
runtime_version.SUFFIX,
54-
'foo.proto',
55-
)
56-
5739
deftest_same_version_allowed(self):
5840
runtime_version.ValidateProtobufRuntimeVersion(
5941
runtime_version.DOMAIN,
@@ -103,34 +85,6 @@ def test_older_runtime_version_disallowed(self):
10385
'foo.proto',
10486
)
10587

106-
deftest_different_suffix_disallowed(self):
107-
withself.assertRaisesRegex(
108-
runtime_version.VersionError,
109-
'Detected mismatched Protobuf Gencode/Runtime version suffixes when'
110-
' loading foo.proto',
111-
):
112-
runtime_version.ValidateProtobufRuntimeVersion(
113-
runtime_version.DOMAIN,
114-
runtime_version.MAJOR,
115-
runtime_version.MINOR,
116-
runtime_version.PATCH,
117-
'-noflag',
118-
'foo.proto',
119-
)
120-
121-
deftest_gencode_one_major_version_older_warning(self):
122-
withself.assertWarnsRegex(
123-
Warning,expected_regex='is exactly one major version older'
124-
):
125-
runtime_version.ValidateProtobufRuntimeVersion(
126-
runtime_version.DOMAIN,
127-
runtime_version.MAJOR-1,
128-
runtime_version.MINOR,
129-
runtime_version.PATCH,
130-
runtime_version.SUFFIX,
131-
'foo.proto',
132-
)
133-
13488

13589
if__name__=='__main__':
13690
unittest.main()

‎python/google/protobuf/runtime_version.py‎

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,33 +92,13 @@ def ValidateProtobufRuntimeVersion(
9292
' Cross-domain usage of Protobuf is not supported.'
9393
)
9494

95-
ifgen_major!=MAJOR:
96-
ifgen_major==MAJOR-1:
97-
if_warning_count<_MAX_WARNING_COUNT:
98-
warnings.warn(
99-
'Protobuf gencode version %s is exactly one major version older'
100-
' than the runtime version %s at %s. Please update the gencode to'
101-
' avoid compatibility violations in the next runtime release.'
102-
% (gen_version,version,location)
103-
)
104-
_warning_count+=1
105-
else:
106-
_ReportVersionError(
107-
'Detected mismatched Protobuf Gencode/Runtime major versions when'
108-
f' loading{location}: gencode{gen_version} runtime{version}.'
109-
f' Same major version is required.{error_prompt}'
110-
)
111-
112-
ifMINOR<gen_minoror (MINOR==gen_minorandPATCH<gen_patch):
95+
if (
96+
MAJOR<gen_major
97+
or (MAJOR==gen_majorandMINOR<gen_minor)
98+
or (MAJOR==gen_majorandMINOR==gen_minorandPATCH<gen_patch)
99+
):
113100
_ReportVersionError(
114101
'Detected incompatible Protobuf Gencode/Runtime versions when loading'
115102
f'{location}: gencode{gen_version} runtime{version}. Runtime version'
116103
f' cannot be older than the linked gencode version.{error_prompt}'
117104
)
118-
119-
ifgen_suffix!=SUFFIX:
120-
_ReportVersionError(
121-
'Detected mismatched Protobuf Gencode/Runtime version suffixes when'
122-
f' loading{location}: gencode{gen_version} runtime{version}.'
123-
f' Version suffixes must be the same.{error_prompt}'
124-
)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp