lmmx / tubeulator

TfL open data interface library
https://tubeulator.vercel.app
MIT License
5 stars 0 forks source link

Deduplicate Meta handling using inheritance #7

Closed lmmx closed 1 year ago

lmmx commented 1 year ago

Rather than repeatedly call LoadMeta, use inheritance

We currently do

LoadMeta(raise_on_unknown_json_key=True).bind_to(ModeDeserialiser)

whereas in the proof of concept I did

class BaseDeserialiser(JSONWizard):
    class Meta(JSONWizard.Meta):
        key_transform_with_load = "PASCAL"

then defined dataclasses like

@dataclass
class Lesson(BaseDeserialiser):
    Def: str
    If: date

@dataclass
class ClassInfo(BaseDeserialiser):
    Class: str
    For: str
    And: str
    From: date
    Values: list[Lesson] = field(default_factory=list)

Either:

  1. The base class is Base(JSONWizard) and defines the Meta method
  2. The base class is Mixin and defines the Meta Method, then use multiple inheritance

The proof of concept shows that option 1 is viable, so that should be used.

lmmx commented 1 year ago

On closer inspection, you cannot inherit raise_on_unknown_json_key = True from a base class (which is probably why I chose to repeatedly call LoadMeta), you don't get the raising behaviour. I'll just add the Meta method instead to all classes.

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import date

from dataclass_wizard import JSONWizard

# class BaseDeserialiser(JSONWizard):
#     class Meta(JSONWizard.Meta):
#         raise_on_unknown_json_key = True
#
#
@dataclass
class Lesson(JSONWizard):
    Def: str
    If: date

    class Meta(JSONWizard.Meta):
        raise_on_unknown_json_key = True
        key_transform_with_load = "PASCAL"

@dataclass
class ClassInfo(JSONWizard):
    Class: str
    For: str
    And: str
    From: date
    Values: list[Lesson] = field(default_factory=list)

    class Meta(JSONWizard.Meta):
        raise_on_unknown_json_key = True
        key_transform_with_load = "PASCAL"

json_string = """
{
  "class": "Math",
  "for": "Beginners",
  "and": "Intermediate",
  "from": "2023-05-25",
  "values": [
    {"def": "Geometry", "if": "2023-06-01"},
    {"def": "Algebra", "if": "2023-07-01"}
  ]
}
"""

class_info = ClassInfo.from_json(json_string)
lmmx commented 1 year ago

Implemented in 7d24b49