Bumping this topic now that the super new Portable Classes are available for use.
As you’ll see from my test code it seems like Anvil still can’t serialise a dictionary with numeric keys (“SimpleDict” in the attached example) whether it’s subclassed and wrapped as a Portable Class, or even if the dict is actually just an attribute of a totally new class (“NumberDict” in the example):
https://anvil.works/build#clone:WZFJQDAKT7WYPMZE=2SVPAUHZC5PIMDACA2KJVRAA
Server Module (copied for convenience)
import anvil.server
from .PortableClassesTest import SimpleDict, NumberDict, JsonDict, print_attributes
# Testing the ability of Anvil Portable Classes to return a dict with numeric keys
@anvil.server.callable
def test_simpledict():
sd = SimpleDict()
print_attributes(sd, "SERVER")
return sd
@anvil.server.callable
def test_numberdict():
nd = NumberDict()
print_attributes(nd, "SERVER")
return nd
@anvil.server.callable
def test_jsondict():
jd = JsonDict()
print_attributes(jd, "SERVER")
return jd
Client Module
from ._anvil_designer import PortableClassesTestTemplate
from anvil import *
import anvil.server
import json
def print_attributes(test_dict, client_or_server):
print(f"This is the {client_or_server} speaking...")
print("Type:", type(test_dict))
for attribute in ("__dict__", "dict", "json"):
if hasattr(test_dict, attribute):
print(f".{attribute}:", getattr(test_dict, attribute))
print(test_dict)
print()
@anvil.server.portable_class
class SimpleDict(dict):
def __init__(self, data={1: "one"}):
self.__dict__.update(data)
def __repr__(self):
return str(vars(self))
@anvil.server.portable_class
class NumberDict:
def __init__(self, data={2: "two"}):
self.dict = data
@anvil.server.portable_class
class JsonDict:
def __init__(self, data={3: "three"}):
self.json = json.dumps(data)
@property
def dict(self):
return {int(k):v for k,v in json.loads(self.json).items()}
def __repr__(self):
return str(self.dict)
class PortableClassesTest(PortableClassesTestTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
for test in ("test_simpledict", "test_numberdict", "test_jsondict"):
try:
result = anvil.server.call(test)
print_attributes(result, "CLIENT")
except Exception as E:
print(E,"\n")
I’ve come up with a workaround (called “JsonDict” above), but I still can’t help thinking: if the whizzy new Portable Classes can handle so much complexity and sophistication already, wouldn’t it be more elegant to handle this requirement at source as part of the Portable Class feature as well?
If there is already a way of serialising dictionaries with numeric keys and I’m just missing something obivous please let me know! (If the answer is soemthing about “Custom Serialisation”, I haven’t got my head around that yet… and it would need to be simpler than my own workaround to obviate the benefit of this Feature Request anyway…) Otherwise please consider this request as a way of resolving a Python/Json “wrinkle” at source and making the Portable Classes truly serialise any class you throw at them?