Skip to content

Support adding hooks for supported objects types #671

Open

Description

@mike0sv

Description

Right now, dec_hooks and enc_hooks are called only if msgspec encounters unknown type. I'd like a way to override dec/enc logic for specific supported types, but there is no way to do it rn. Possible solutions:

  1. add new argument with Dict[Type[T], Callable[[T], Any] that works even if T is subclass of Struct or any other supported type
  2. inspect argument type annotation for callables passed to dec_hooks and enc_hooks. If it is annotated with some type, use hook even if type supported natively
  3. introduce special (possibly dunder method) that can override default enc/dec logic. It can look something like this in python: decoded = if hasattr(obj.__class__, "__decode__") obj.__decode__(obj) else <native logic>. This will only work for Struct subclasses though

Activity

  1. changed the title [-]Support adding hooks for supported objects[/-] [+]Support adding hooks for supported objects types[/+] on Apr 19, 2024
  2. wikiped commented on Apr 24, 2024

    @wikiped

    Linked: #669

  3. kevin-lee-dialpad commented on May 7, 2024

    @kevin-lee-dialpad

    we have the same problem.
    msgspec json encoder supports a lot more types by default which sometimes isn't what we want(ex. sometimes we'd rather have serialization to fail rather than letting it pass and create an encoded data that we wouldn't know what type to decode it to by the time it gets to deserialization step).
    and sometimes the way that msgspec json serializes certain supported types just isn't what we want.

    both of these issues can be dealt with if there's a way to override behaviour for certain supported types.

  4. pohlt commented on Apr 9, 2025

    @pohlt

    Same problem here: I get timestamps in milliseconds and have to convert them.

    As a workaround I currently define a new datetime subclass class Timestamp(datetime): ... and register a decoder hook for this Timestamp class. Works, but feels wrong.

  5. kunesj commented on Oct 17, 2025

    @kunesj

    I encountered this problem with subclasses of dict.

    I'm using ICal Components from the icalendar package, and I would like to serialize them into strings with comp.to_ical(), but they inherit from dict, so msgspec completely ignores my enc_hook and serializes them as dicts.

    That would have been acceptable if all information was saved in dict keys, but it's not, so for example sub-components are completely missing in the serialized data.

    import icalendar
    import msgspec
    
    data = """
    BEGIN:VCALENDAR
    PRODID:-//Google Inc//Google Calendar 70.9054//EN
    VERSION:2.0
    CALSCALE:GREGORIAN
    METHOD:PUBLISH
    BEGIN:VEVENT
    SUMMARY:test
    END:VEVENT
    END:VCALENDAR
    """
    calendar = icalendar.Calendar.from_ical(data, multiple=False)
    
    calendar.to_ical()
    # b'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Google Inc//Google Calendar 70.9054//EN\r\nCALSCALE:GREGORIAN\r\nMETHOD:PUBLISH\r\nBEGIN:VEVENT\r\nSUMMARY:test\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'
    
    msgspec.json.encode(calendar, enc_hook=lambda obj: obj.to_ical().decode())
    # b'{"PRODID":"-//Google Inc//Google Calendar 70.9054//EN","VERSION":"2.0","CALSCALE":"GREGORIAN","METHOD":"PUBLISH"}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions