mirror of
https://github.com/lancedb/lancedb.git
synced 2026-11-13 14:16:54 +00:00
docs(function): define forward-compatible version projection (#4863)
Clarify `FunctionVersion` forward compatibility: unknown top-level fields are accepted during decoding and omitted from canonical JSON, while all defined fields and the open `image.descriptor` content retain their values. Extend the existing Rust and Python canonical round-trip tests to assert the complete projected object, including future discriminator values. This documents and tests the existing behavior; it does not change runtime serialization or promise lossless retention of unknown top-level fields. Related: ENT-2176.
This commit is contained in:
@@ -469,6 +469,12 @@ _ObjectVersion = Annotated[
|
||||
class FunctionVersion(_RemoteValue):
|
||||
"""A pinned object revision, independent of its executable image digest.
|
||||
|
||||
Unknown top-level fields from newer servers are accepted for forward
|
||||
decoding, but they are not exposed on this value and are omitted from
|
||||
``to_canonical_json()``. Known fields retain their complete values, while
|
||||
unknown fields inside the open ``image.descriptor`` mapping remain
|
||||
available.
|
||||
|
||||
``name`` and ``namespace_path`` are the Function's parts, as a
|
||||
[SecretReference][lancedb.functions.SecretReference] carries a Secret's;
|
||||
they are what [get_function][lancedb.db.DBConnection.get_function] takes.
|
||||
|
||||
@@ -301,10 +301,15 @@ def test_unknown_fields_and_discriminators_are_forward_decodable():
|
||||
|
||||
version = FunctionVersion.from_json(json.dumps(value))
|
||||
assert version.image.descriptor["future_interface"] == {"kind": "wasm"}
|
||||
assert json.loads(version.to_canonical_json())["image"]["descriptor"][
|
||||
"future_interface"
|
||||
] == {"kind": "wasm"}
|
||||
assert version.signature.output.kind == "future_output_shape"
|
||||
assert not hasattr(version, "future_version_metadata")
|
||||
|
||||
canonical = json.loads(version.to_canonical_json())
|
||||
expected = json.loads(fixture("remote_function_version.canonical.json"))
|
||||
expected["image"]["descriptor"]["future_interface"] = {"kind": "wasm"}
|
||||
expected["signature"]["output"]["kind"] = "future_output_shape"
|
||||
assert canonical == expected
|
||||
assert "future_version_metadata" not in canonical
|
||||
|
||||
|
||||
def test_function_application_uses_rename_columns_only():
|
||||
|
||||
@@ -570,6 +570,12 @@ impl<'de> Deserialize<'de> for RowTimeoutSeconds {
|
||||
///
|
||||
/// The Function is named by its parts, `name` and `namespace_path`, the way a
|
||||
/// [`SecretReference`](crate::secrets::SecretReference) names a Secret.
|
||||
///
|
||||
/// Unknown top-level fields from newer servers are accepted for forward
|
||||
/// decoding, but they are not part of this value and are omitted from
|
||||
/// canonical JSON. Known fields retain their complete values, while unknown
|
||||
/// fields inside the open [`FunctionImage::descriptor`] JSON object remain
|
||||
/// available.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionVersion {
|
||||
name: String,
|
||||
|
||||
@@ -182,13 +182,17 @@ fn unknown_fields_and_discriminators_are_forward_decodable() {
|
||||
let version = FunctionVersion::from_json(&result.to_string()).expect("future remote value");
|
||||
assert_eq!(version.image().descriptor["future_interface"]["version"], 2);
|
||||
assert_eq!(version.signature().output.kind, "future_output_shape");
|
||||
assert_eq!(
|
||||
serde_json::from_str::<Value>(
|
||||
&version.to_canonical_json().expect("canonical future value")
|
||||
)
|
||||
.expect("canonical JSON")["image"]["descriptor"]["future_interface"],
|
||||
serde_json::json!({"version": 2})
|
||||
);
|
||||
let canonical: Value =
|
||||
serde_json::from_str(&version.to_canonical_json().expect("canonical future value"))
|
||||
.expect("canonical JSON");
|
||||
|
||||
let mut expected: Value =
|
||||
serde_json::from_str(fixture("remote_function_version.canonical.json").trim())
|
||||
.expect("canonical FunctionVersion fixture");
|
||||
expected["image"]["descriptor"]["future_interface"] = serde_json::json!({"version": 2});
|
||||
expected["signature"]["output"]["kind"] = Value::String("future_output_shape".to_string());
|
||||
assert_eq!(canonical, expected);
|
||||
assert!(canonical.get("future_version_metadata").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user