cvat/tests/python/sdk/test_api_wrappers.py

125 lines
3.6 KiB
Python
Raw Normal View History

2025-09-16 01:19:40 +00:00
# Copyright (C) CVAT.ai Corporation
#
# SPDX-License-Identifier: MIT
import pickle
from copy import deepcopy
from cvat_sdk import models
from deepdiff import DeepDiff
def test_models_do_not_change_input_values():
# Nested containers may be modified during the model input data parsing.
# This can lead to subtle memory errors, which are very hard to find.
original_input_data = {
"name": "test",
"labels": [
{
"name": "cat",
"attributes": [
{
"default_value": "yy",
"input_type": "text",
"mutable": False,
"name": "x",
"values": ["yy"],
},
{
"default_value": "1",
"input_type": "radio",
"mutable": False,
"name": "y",
"values": ["1", "2"],
},
],
}
],
}
input_data = deepcopy(original_input_data)
models.TaskWriteRequest(**input_data)
assert DeepDiff(original_input_data, input_data) == {}
def test_models_do_not_store_input_collections():
# Avoid depending on input data for collection fields after the model is initialized.
# This can lead to subtle memory errors and unexpected behavior
# if the original input data is modified.
input_data = {
"name": "test",
"labels": [
{
"name": "cat1",
"attributes": [
{
"default_value": "yy",
"input_type": "text",
"mutable": False,
"name": "x",
"values": ["yy"],
},
{
"default_value": "1",
"input_type": "radio",
"mutable": False,
"name": "y",
"values": ["1", "2"],
},
],
},
{"name": "cat2", "attributes": []},
],
}
model = models.TaskWriteRequest(**input_data)
model_data1 = model.to_dict()
# Modify input value containers
input_data["labels"][0]["attributes"].clear()
input_data["labels"][1]["attributes"].append(
{
"default_value": "",
"input_type": "text",
"mutable": True,
"name": "z",
}
)
input_data["labels"].append({"name": "dog"})
model_data2 = model.to_dict()
assert DeepDiff(model_data1, model_data2) == {}
def test_models_do_not_return_internal_collections():
# Avoid returning internal data for mutable collection fields.
# This can lead to subtle memory errors and unexpected behavior
# if the returned data is modified.
input_data = {
"name": "test",
"labels": [],
}
model = models.TaskWriteRequest(**input_data)
model_data1 = model.to_dict()
model_data1_original = deepcopy(model_data1)
# Modify an output value container
model_data1["labels"].append({"name": "dog"})
model_data2 = model.to_dict()
assert DeepDiff(model_data1_original, model_data2) == {}
def test_models_are_pickleable():
model = models.PatchedLabelRequest(id=5, name="person")
pickled_model = pickle.dumps(model)
unpickled_model = pickle.loads(pickled_model)
assert unpickled_model.id == model.id
assert unpickled_model.name == model.name