[Python] Compatible xlang read silently drops fields when the peer writes camelCase/PascalCase names

オープン 初心者向け
#4,202 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
85/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
data

調査の方向性

python/pyfory/meta/typedef.py、特に TypeDef._resolve_field_names_from_tag_ids() を検査してください。これは snake_case を camelCase にのみ変換します。docs/specification/xlang_serialization_spec.md を読んでフィールド識別子の規則を確認してください。camelCase のワイヤ名が snake_case のローカルフィールドと一致するように逆マッピングを追加し、その後 issue の再現を実行して Local(created_at=7, foo_url='hi') を確認してください。

索引モデルが issue の本文から書いたものです。

説明

Search before asking
  • I have searched the issues and found no similar issue.
Version

main (1.8.0.dev0)

Component(s)

Python

Minimal reproduce step

A compatible xlang read matches the peer's wire field name against the local class fields.
The matcher only converts snake_case to camelCase, so a peer that writes the declared
field name (camelCase/PascalCase) cannot be matched to a local class that declares the
same field in snake_case.

The read succeeds, but the value of every unmatched field is read and discarded, so the
local field keeps its default value. No error is raised.

from dataclasses import make_dataclass
from pyfory import Fory

Peer = make_dataclass("Peer", [("createdAt", int), ("fooURL", str)])
Local = make_dataclass("Local", [("created_at", int), ("foo_url", str)])

writer = Fory(xlang=True, compatible=True)
writer.register(Peer, name="demo.Peer")
data = writer.serialize(Peer(7, "hi"))

reader = Fory(xlang=True, compatible=True)
reader.register(Local, name="demo.Peer")
print(reader.deserialize(data))
# Local(created_at=0, foo_url='')  <- both values lost
What did you expect to see?

Local(created_at=7, foo_url='hi').

What did you see instead?

Local(created_at=0, foo_url=''). The deserialization reports success.

Anything Else?

This follows the field-identity rule of the xlang specification: the field identifier is the
snake_case field name (docs/specification/xlang_serialization_spec.md, "Field identifier
is the tag ID if present, otherwise the snake_case field name"), and compatible decoders must
match fields by name ("must still match fields by name or tag ID rather than relying only on
position"). A camelCase wire name and a snake_case local name denote the same field, so the
reader has to match the two in both directions.

The matcher is TypeDef._resolve_field_names_from_tag_ids() in python/pyfory/meta/typedef.py.
It already converts snake_case to camelCase, but not the other way round. Peers that write
the declared name are the ones that hit the missing direction: the Rust runtime writes the raw
field name, and Python itself writes the raw field name as well.

Related: #4187 covers the unspecified snake_case conversion itself. This issue is about the
read side matching a peer field to the local field, which does not depend on which conversion a
peer uses to write its name.

Are you willing to submit a PR?
  • I'm willing to submit a PR!
主要言語
Java
スター
4.6k
フォーク
470
平均マージ
9時間 28分
マージ済み PR(30日)
33

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/fory のほかの issue

apache/fory の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。