This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new c5bb74fda chore(python): handle duplicate field names (#3384)
c5bb74fda is described below

commit c5bb74fda96730b1671a0deea456918b16cd8c05
Author: Eyad Hazem <[email protected]>
AuthorDate: Sat Feb 28 19:01:36 2026 +0200

    chore(python): handle duplicate field names (#3384)
    
    ## Why?
    
    This PR handles the duplicate of field names for inheritance.
    
    ## What does this PR do?
    
    The handling is done by making every child class's field override its
    parent's till the most-derived field kept.
    - First, we iterate over the full class MRO (cls.__mro__) to extract
    field metadata from all parent classes.
    - Then, deduplicate fields so that each field name appears only once in
    the resulting list with keeping the child class definition if a field is
    shadowed.
    - Finally, added some tests to cover:
        - Single-level inheritance
        - Multi-level inheritance
        - Field shadowing in child and grandchild classes
        - Deduplication of overridden fields
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
---
 python/pyfory/meta/typedef_encoder.py             |  7 ---
 python/pyfory/tests/test_duplicate_field_names.py | 55 +++++++++++++++++++++++
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/python/pyfory/meta/typedef_encoder.py 
b/python/pyfory/meta/typedef_encoder.py
index 5e0824c50..d93996c6c 100644
--- a/python/pyfory/meta/typedef_encoder.py
+++ b/python/pyfory/meta/typedef_encoder.py
@@ -15,7 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-from collections import Counter
 
 from pyfory.meta.typedef import (
     FieldInfo,
@@ -61,12 +60,6 @@ def encode_typedef(type_resolver, cls, include_fields: bool 
= True):
     """
     if include_fields:
         field_infos = build_field_infos(type_resolver, cls)
-        # Check for duplicate field names
-        field_names = [field_info.name for field_info in field_infos]
-        duplicate_field_names = [name for name, count in 
Counter(field_names).items() if count > 1]
-        if duplicate_field_names:
-            # TODO: handle duplicate field names for inheritance in future
-            raise ValueError(f"Duplicate field names: {duplicate_field_names}")
     else:
         field_infos = []
 
diff --git a/python/pyfory/tests/test_duplicate_field_names.py 
b/python/pyfory/tests/test_duplicate_field_names.py
new file mode 100644
index 000000000..26603603a
--- /dev/null
+++ b/python/pyfory/tests/test_duplicate_field_names.py
@@ -0,0 +1,55 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""
+Tests for field shadowing in inheritance.
+"""
+
+from dataclasses import dataclass
+from pyfory import Fory
+from pyfory.meta.typedef_encoder import encode_typedef
+
+
+@dataclass
+class Parent:
+    name: str
+    value: int
+
+
+@dataclass
+class ChildWithShadow(Parent):
+    name: str  # Shadows Parent.name
+    extra: float
+
+
+def test_shadowed_fields_serialization():
+    """Serialization with shadowed and inherited fields."""
+    fory = Fory(xlang=True)
+    fory.register(Parent, namespace="test", typename="Parent")
+    fory.register(ChildWithShadow, namespace="test", 
typename="ChildWithShadow")
+
+    # Verify TypeDef has exactly 3 fields (no duplicate 'name')
+    typedef = encode_typedef(fory.type_resolver, ChildWithShadow)
+    assert len(typedef.fields) == 3
+
+    obj = ChildWithShadow(name="shadowed", value=10, extra=3.14)
+    data = fory.serialize(obj)
+    result = fory.deserialize(data)
+
+    assert result.name == "shadowed"
+    assert result.value == 10  # inherited field
+    assert result.extra == 3.14


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to