+171
-81
lines changedFilter options
+171
-81
lines changed Original file line number Diff line number Diff line change
@@ -319,3 +319,69 @@ jobs:
319
319
for test in $TESTS; do
320
320
python -m unittest -v $test
321
321
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 }})
Original file line number Diff line number Diff 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
+
for proto in ${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
+
for proto in ${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[@]}
Original file line number Diff line number Diff line change
@@ -128,13 +128,16 @@ class of the options message. The name of the class is required in case
128
128
"""
129
129
self._features = None
130
130
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
133
136
self._options_class_name = options_class_name
134
137
self._serialized_options = serialized_options
135
138
136
139
# Does this descriptor have non-default options?
137
-
self.has_options = (self._options is not None) or (
140
+
self.has_options = (self._original_options is not None) or (
138
141
self._serialized_options is not None
139
142
)
140
143
@@ -186,7 +189,8 @@ def _ResolveFeatures(self, edition, raw_options):
186
189
187
190
def _LazyLoadOptions(self):
188
191
"""Lazily initializes descriptor options towards the end of the build."""
189
-
if self._loaded_options:
192
+
if self._options and self._loaded_options == self._options:
193
+
# If neither has been reset by gencode, use the cache.
190
194
return
191
195
192
196
# pylint: disable=g-import-not-at-top
@@ -206,12 +210,12 @@ def _LazyLoadOptions(self):
206
210
descriptor_pb2.Edition.Value(edition), options_class()
207
211
)
208
212
with _lock:
209
-
self._loaded_options = options_class()
213
+
self._options = self._loaded_options = options_class()
210
214
if not self._features:
211
215
self._features = features
212
216
else:
213
217
if not self._serialized_options:
214
-
options = self._options
218
+
options = self._original_options
215
219
else:
216
220
options = _ParseOptions(options_class(), self._serialized_options)
217
221
@@ -220,13 +224,13 @@ def _LazyLoadOptions(self):
220
224
descriptor_pb2.Edition.Value(edition), options
221
225
)
222
226
with _lock:
223
-
self._loaded_options = options
227
+
self._options = self._loaded_options = options
224
228
if not self._features:
225
229
self._features = features
226
230
if options.HasField('features'):
227
231
options.ClearField('features')
228
232
if not options.SerializeToString():
229
-
self._loaded_options = options_class()
233
+
self._options = self._loaded_options = options_class()
230
234
self.has_options = False
231
235
232
236
def GetOptions(self):
@@ -235,9 +239,10 @@ def GetOptions(self):
235
239
Returns:
236
240
The options set on this descriptor.
237
241
"""
238
-
if not self._loaded_options:
242
+
# If either has been reset by gencode, reload options.
243
+
if not self._options or not self._loaded_options:
239
244
self._LazyLoadOptions()
240
-
return self._loaded_options
245
+
return self._options
241
246
242
247
243
248
class _NestedDescriptorBase(DescriptorBase):
Original file line number Diff line number Diff line change
@@ -829,6 +829,13 @@ def _AddPropertiesForExtensions(descriptor, cls):
829
829
pool = descriptor.file.pool
830
830
831
831
def _AddStaticMethods(cls):
832
+
833
+
def RegisterExtension(_):
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)
832
839
def FromString(s):
833
840
message = cls()
834
841
message.MergeFromString(s)
Original file line number Diff line number Diff line change
@@ -36,24 +36,6 @@ def test_cross_domain_disallowed(self):
36
36
gencode_domain, 1, 2, 3, '', 'foo.proto'
37
37
)
38
38
39
-
def test_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
-
with self.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
-
57
39
def test_same_version_allowed(self):
58
40
runtime_version.ValidateProtobufRuntimeVersion(
59
41
runtime_version.DOMAIN,
@@ -103,34 +85,6 @@ def test_older_runtime_version_disallowed(self):
103
85
'foo.proto',
104
86
)
105
87
106
-
def test_different_suffix_disallowed(self):
107
-
with self.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
-
def test_gencode_one_major_version_older_warning(self):
122
-
with self.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
-
134
88
135
89
if __name__ == '__main__':
136
90
unittest.main()
Original file line number Diff line number Diff line change
@@ -92,33 +92,13 @@ def ValidateProtobufRuntimeVersion(
92
92
' Cross-domain usage of Protobuf is not supported.'
93
93
)
94
94
95
-
if gen_major != MAJOR:
96
-
if gen_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
-
if MINOR < gen_minor or (MINOR == gen_minor and PATCH < gen_patch):
95
+
if (
96
+
MAJOR < gen_major
97
+
or (MAJOR == gen_major and MINOR < gen_minor)
98
+
or (MAJOR == gen_major and MINOR == gen_minor and PATCH < gen_patch)
99
+
):
113
100
_ReportVersionError(
114
101
'Detected incompatible Protobuf Gencode/Runtime versions when loading'
115
102
f' {location}: gencode {gen_version} runtime {version}. Runtime version'
116
103
f' cannot be older than the linked gencode version. {error_prompt}'
117
104
)
118
-
119
-
if gen_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
-
)
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4