From 7dfb10cb51df2ea875d7532cab24b25ae9b58f93 Mon Sep 17 00:00:00 2001 From: Salad Dais Date: Thu, 21 Jul 2022 08:05:25 +0000 Subject: [PATCH] Make TextureEntry deserialization lazy in the ObjectUpdate case too --- hippolyzer/lib/base/helpers.py | 6 +++++- hippolyzer/lib/base/serialization.py | 6 ++++++ hippolyzer/lib/base/templates.py | 2 +- tests/proxy/test_object_manager.py | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/hippolyzer/lib/base/helpers.py b/hippolyzer/lib/base/helpers.py index 4848c4f..7bb235e 100644 --- a/hippolyzer/lib/base/helpers.py +++ b/hippolyzer/lib/base/helpers.py @@ -4,6 +4,7 @@ import codecs import functools import os +import lazy_object_proxy import pkg_resources import re import weakref @@ -19,7 +20,7 @@ def _with_patched_multidict(f): # There's no way to tell pprint "hey, this is a dict, # this is how you access its items." A lot of the formatting logic # is in the module-level `_safe_repr()` which we don't want to mess with. - # Instead, pretend our MultiDict has dict's __repr__ and while we're inside + # Instead, pretend our MultiDict has dict's __repr__ while we're inside # calls to pprint. Hooray. orig_repr = MultiDict.__repr__ if orig_repr is dict.__repr__: @@ -67,6 +68,9 @@ class HippoPrettyPrinter(PrettyPrinter): return f"({reprs})" def pformat(self, obj: object, *args, **kwargs) -> str: + # Unwrap lazy object proxies before pprinting them + if isinstance(obj, lazy_object_proxy.Proxy): + obj = obj.__wrapped__ if isinstance(obj, (bytes, str)): return self._str_format(obj) return self._base_pformat(obj, *args, **kwargs) diff --git a/hippolyzer/lib/base/serialization.py b/hippolyzer/lib/base/serialization.py index 83a1276..255e5e6 100644 --- a/hippolyzer/lib/base/serialization.py +++ b/hippolyzer/lib/base/serialization.py @@ -1339,6 +1339,12 @@ class TypedBytesBase(SerializableBase, abc.ABC): return self._spec.default_value() +class TypedBytesGreedy(TypedBytesBase): + def __init__(self, spec, empty_is_none=False, check_trailing_bytes=True, lazy=False): + self._bytes_tmpl = BytesGreedy() + super().__init__(spec, empty_is_none, check_trailing_bytes, lazy=lazy) + + class TypedByteArray(TypedBytesBase): def __init__(self, len_spec, spec, empty_is_none=False, check_trailing_bytes=True, lazy=False): self._bytes_tmpl = ByteArray(len_spec) diff --git a/hippolyzer/lib/base/templates.py b/hippolyzer/lib/base/templates.py index 0f2f08f..ff09c95 100644 --- a/hippolyzer/lib/base/templates.py +++ b/hippolyzer/lib/base/templates.py @@ -1295,7 +1295,7 @@ TE_SERIALIZER = se.Dataclass(TextureEntryCollection) @se.subfield_serializer("ObjectImage", "ObjectData", "TextureEntry") class TextureEntrySubfieldSerializer(se.SimpleSubfieldSerializer): EMPTY_IS_NONE = True - TEMPLATE = TE_SERIALIZER + TEMPLATE = se.TypedBytesGreedy(TE_SERIALIZER, empty_is_none=True, lazy=True) DATA_PACKER_TE_TEMPLATE = se.TypedByteArray( diff --git a/tests/proxy/test_object_manager.py b/tests/proxy/test_object_manager.py index 0b31211..17f6873 100644 --- a/tests/proxy/test_object_manager.py +++ b/tests/proxy/test_object_manager.py @@ -289,7 +289,7 @@ class RegionObjectManagerTests(ObjectManagerTestMixin, unittest.IsolatedAsyncioT self.message_handler.handle(msg) events = self.object_addon.events self.assertEqual(2, len(events)) - self.assertEqual({"Position"}, events[1][2]) + self.assertEqual({"Position", "TextureEntry"}, events[1][2]) def test_region_position(self): parent = self._create_object(pos=(0.0, 1.0, 0.0))