dataclassio multitype fixes/tidying

This commit is contained in:
Eric 2024-02-01 12:35:00 -08:00
parent 3186ff6b50
commit dc6d29de22
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
8 changed files with 86 additions and 32 deletions

40
.efrocachemap generated
View File

@ -4060,26 +4060,26 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "4061f6114403c60ce1553d2b95c6fd7f",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "c73d4beea86082419fa0dee9cf8e93be",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "928c17c937e26d2fdc9edc8bc1e07659",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "07a90a9ee49ccfcf4cb0fcbccd0e1a04",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "aa4929306878a5e757be36bbd80cb3b3",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "6579bfe457770767a35ce69513433273",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "0eb96f2dfd3798621dd35d3693e596f7",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "21ff8796c4e459d4087a68d02b998576",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "a69ade336e8d9574919debda154ca2ec",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "ce625368b6392bc3d9c6f033b1255c6f",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0b606c6c6f4774dc9cfebfab347d6271",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "56878ae9435c3b99a62319e016418dff",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "461c5e567f8bf9726a1b7f5ced7e7418",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "c6a85daf172fee978c7deafb3b50fc21",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "42121063ca6dc6a446a331b2ea4dc707",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "94a0a0bec30f85b0397fb1925ef54e33",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f9f983439f6b2a5cc92e2c8c575b66bb",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "ec5f0294584602e88e071eb336b671fd",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "6c49a9829024ff91e2d07dbaf2c75184",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f82d8ed05ca2fa9a3bef869e3ce6ac4b",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "7169141b846e3c15160f3405bd1ed2ce",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "04869210f06ff8c00fb6d68a69f6b335",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "e28eac17f30edddc35c483fbc4e69fc5",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "342aee2d1f2965caed811a72888cc7f1",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "c091240edeeeac378ffe86ce1421decc",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "c959d3661ea83a2f9920da6d6d355fd9",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "9015fb2718d6fc5a9a9bd95b0086bde6",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "dfcd11db04c0071b7e5032673c2dad43",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "8a0ad295f62fc9cfa4a71d30038b0c20",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "21f2f9aecbd0c60b8e125f206ebd44c2",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "df5d59cf4b6da427b3e2bb4d1136cf32",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "72f5ab8cd24ce31b8bbfe08ce691bf7b",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "11280b6cbec7a21574f0e8e29c379bea",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "766b8ad86046a92fa5fa25a0a7ad88ae",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "10ac2e99587552edfc3eb089ea69ede4",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8cd63147b79d8866af817d01dcc8f5eb",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "061de20725a847ac6ed327d8c2e5b905",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "6556a6e96f2a360a4006f2c2b7a5a1f1",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "1324063eeaeda2c72f7e133984fa838b",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "3c6b96c3a63fc53819425f8872264aa8",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "8709ad96140d71760c2f493ee8bd7c43",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "ee829cd5488e9750570dc6f602d65589",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "8709ad96140d71760c2f493ee8bd7c43",

View File

@ -1,4 +1,4 @@
### 1.7.33 (build 21764, api 8, 2024-01-31)
### 1.7.33 (build 21766, api 8, 2024-02-01)
- Stress test input-devices are now a bit smarter; they won't press any buttons
while UIs are up (this could cause lots of chaos if it happened).
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 21764
TARGET_BALLISTICA_BUILD = 21766
TARGET_BALLISTICA_VERSION = '1.7.33'

View File

@ -14,7 +14,7 @@ Mac:
(brew install python3).
Linux (x86_64):
- Server binaries are currently compiled against Ubuntu 20 LTS.
- Server binaries are currently compiled against Ubuntu 22 LTS.
Raspberry Pi:
- The server binary was compiled on a Raspberry Pi 4 running Raspbian Buster.

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21764;
const int kEngineBuildNumber = 21766;
const char* kEngineVersion = "1.7.33";
const int kEngineApiVersion = 8;

View File

@ -5,6 +5,7 @@
from __future__ import annotations
import copy
import datetime
from enum import Enum
from dataclasses import field, dataclass
@ -1159,6 +1160,7 @@ class MTTestClass2(MTTestBase):
def test_multi_type() -> None:
"""Test IOMultiType stuff."""
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
# Test converting single instances back and forth.
val1: MTTestBase = MTTestClass1(ival=123)
@ -1179,6 +1181,17 @@ def test_multi_type() -> None:
assert dataclass_from_dict(MTTestBase, outdict) == val1
assert dataclass_from_dict(MTTestBase, outdict2) == val2
# Trying to load as a multi-type should fail if there is no type
# value present.
outdictmod = copy.deepcopy(outdict)
del outdictmod[tpname]
with pytest.raises(ValueError):
dataclass_from_dict(MTTestBase, outdictmod)
# However it should work when loading an exact type. This can be
# necessary to gracefully upgrade old data to multi-type form.
dataclass_from_dict(MTTestClass1, outdictmod)
# Now test our multi-type embedded in other classes. We should be
# able to throw a mix of things in there and have them deserialize
# back the types we started with.
@ -1253,3 +1266,33 @@ def test_multi_type() -> None:
outdict = dataclass_to_dict(container5)
container5b = dataclass_from_dict(_TestContainerClass5, outdict)
assert container5 == container5b
# Optionals.
@ioprepped
@dataclass
class _TestContainerClass6:
obj: MTTestBase | None
container6 = _TestContainerClass6(obj=None)
outdict = dataclass_to_dict(container6)
container6b = dataclass_from_dict(_TestContainerClass6, outdict)
assert container6 == container6b
container6 = _TestContainerClass6(obj=MTTestClass2('fwr'))
outdict = dataclass_to_dict(container6)
container6b = dataclass_from_dict(_TestContainerClass6, outdict)
assert container6 == container6b
@ioprepped
@dataclass
class _TestContainerClass7:
obj: Annotated[
MTTestBase | None,
IOAttrs('o', soft_default=None),
]
container7 = _TestContainerClass7(obj=None)
outdict = dataclass_to_dict(container7)
container7b = dataclass_from_dict(_TestContainerClass7, {})
assert container7 == container7b

View File

@ -69,16 +69,21 @@ class IOMultiType(Generic[EnumT]):
This enables usage of high level base classes (for example
a 'Message' type) in dataclasses, with dataclassio automatically
serializing/deserializing subclass instances using provided
per-class type-ids.
serializing & deserializing subclass instances based on their
type.
See tests/test_efro/test_dataclassio.py for an example of this.
Standard usage involves creating a class which inherits from this
one that acts as a 'registry', and then creating dataclass classes
inheriting from that registry class. Dataclassio will then do the
right thing when that registry class is used in type annotations.
See tests/test_efro/test_dataclassio.py for examples.
"""
# Dataclasses inheriting from an IOMultiType will store a type-id
# with this key in their serialized data. This value can be
# overridden in IOMultiType subclasses in case of conflicts.
ID_STORAGE_NAME = '_iotype'
ID_STORAGE_NAME = '_dciotype'
@classmethod
def get_type(cls, type_id: EnumT) -> type[Self]:

View File

@ -64,9 +64,15 @@ class _Inputter:
outcls: type[Any]
# If we're dealing with a multi-type class, figure out the
# top level type we're going to.
if issubclass(self._cls, IOMultiType):
# If we're dealing with a multi-type subclass which is NOT a
# dataclass, we must rely on its stored type to figure out
# what type of dataclass we're going to. If we are a dataclass
# then we already know what type we're going to so we can
# survive without this, which is often necessary when reading
# old data that doesn't have a type id attr yet.
if issubclass(self._cls, IOMultiType) and not dataclasses.is_dataclass(
self._cls
):
type_id_val = values.get(self._cls.ID_STORAGE_NAME)
if type_id_val is None:
raise ValueError(
@ -265,7 +271,7 @@ class _Inputter:
args: dict[str, Any] = {}
for rawkey, value in values.items():
# Ignore _iotype or whatnot.
# Ignore _dciotype or whatnot.
if type_id_store_name is not None and rawkey == type_id_store_name:
continue