-
Notifications
You must be signed in to change notification settings - Fork 356
feat(java/python/rust/go/c++): align nullable meta for xlang struct fields serialization #3093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
chaokunyang
merged 35 commits into
apache:main
from
chaokunyang:align_xlang_ref_nullable
Dec 30, 2025
Merged
feat(java/python/rust/go/c++): align nullable meta for xlang struct fields serialization #3093
chaokunyang
merged 35 commits into
apache:main
from
chaokunyang:align_xlang_ref_nullable
Dec 30, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14d994d to
1f2f649
Compare
1f2f649 to
9471a2e
Compare
pandalee99
approved these changes
Dec 26, 2025
6b57909 to
b772a7f
Compare
b772a7f to
36d3243
Compare
877f7af to
e0205bd
Compare
Use lazy_import for numpy and handle the case when numpy is not available by comparing arrays as lists instead.
…r test The circular reference changes in xread_ref/xread_no_ref broke the xlang protocol because they changed how read_ref_ids is populated. This reverts those changes. Also skip the circular reference test for XLANG mode since XLANG doesn't support true circular references - objects must be registered after they are fully constructed.
Also skip the dict3 circular reference test for XLANG mode since it also uses circular references (dict3 containing itself).
Add back the ref_tracking check before pushing -1 to read_ref_ids. Without this check, when ref_tracking is disabled, the code would fail because NoRefResolver doesn't have read_ref_ids.
This commit fixes cross-language compatibility issues between Java and Python when handling Object/Any types in xlang mode: 1. Java FieldTypes.java: Treat Object.class as nullable in xlang mode to match Python's typing.Any behavior 2. Java TypeResolver.java: Update isFieldNullable() to treat Object.class as nullable in xlang mode 3. Java Fingerprint.java: Include boxed types and Object.class in nullable check for struct fingerprint computation 4. Python typedef.py: Treat typing.Any as nullable in xlang mode, and default ref tracking to false in xlang mode (matching Java's behavior) 5. Python _fory.py and serialization.pyx: Fix circular reference handling by not pushing -1 to read_ref_ids when called from xread_ref, since try_preserve_ref_id already handles the ref_id tracking
Object (Java) and typing.Any (Python) should NOT be nullable by default in xlang mode. Only Optional[T] types should be nullable. This fixes the fingerprint mismatch issue while maintaining the correct xlang semantics that non-Optional types are non-nullable.
Numpy is already a build dependency in pyproject.toml, so it's always installed. Remove the lazy import and conditional check for numpy.
The function just returned the nullable parameter, making it unnecessary. Inline def.nullable directly at the call sites.
deefc6c to
4a7a14f
Compare
Document xlang field nullable/ref defaults: - Non-nullable by default in xlang mode - Only Optional<T> types are nullable - Ref flags only written for nullable fields - Language-specific examples and customization
Allow adding new docs without renumbering: - index: 0 - getting-started: 10 - serialization: 30 - field-nullability: 40 - zero-copy: 50 - row_format: 60 - troubleshooting: 70
- field-nullability.md: focused on null handling only - reference-tracking.md: new doc for shared/circular refs
Allow field() to be called without the id parameter. When omitted, defaults to -1 which uses field name encoding instead of tag ID. This aligns with Java's @ForyField(id default -1).
This was referenced Dec 30, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Why?
The cross-language (xlang) struct serialization had inconsistent nullable and ref flag handling across different language implementations (Java, Rust, C++, Go, Python). This caused:
What does this PR do?
Core Protocol Alignment
Unified nullable semantics across all languages:
Optionaltypes and boxed primitives)nullable=true- non-nullable fields skip the ref flag entirelyKey changes per language:
Fingerprint.javafor consistent struct fingerprint computation; updated serializers for xlang nullable defaultsfield_need_write_ref_into()to only check nullable flagfield_is_nullablelogic; fixed map null entry handling; aligned struct/ext skip logicCode Refactoring (Java)
FieldInfoandFieldTypesfromClassDef.java(reduced from ~900 lines to ~3 lines)ForyLogger,LogLevel,Logger,Slf4jLogger)TypeRefwith additional type utilitiesTypeResolverwith improved type handlingBug Fixes
skip_structandskip_extto handle different struct type categories correctly (COMPATIBLE_STRUCT, NAMED_COMPATIBLE_STRUCT, NAMED_STRUCT, STRUCT)CI Improvements
python_xlangjob for Python cross-language testingTest Updates
std::optional<T>toTin C++ test structs to match xlang semanticsRelated issues
#1017
#2982
#2906
Does this PR introduce any user-facing change?
@ForyField(nullable = true)or useOptional<T>types.Benchmark
N/A (Protocol alignment, no performance-related changes)