question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

Extend dict keys to allow for string literals?

See original GitHub issue

Currently, string literals canā€™t be used as dict keys in a Struct. See example below:

from typing import Literal
from msgspec import Struct, json

AorB = Literal["a", "b"]

class Test(Struct):
    d: dict[AorB, float]

data = Test(d={'a': 1.0, 'b': 2.0})
encoded = json.encode(data)
print(encoded)

decoded = json.decode(encoded, type=Test) # TypeError: JSON doesn't support dicts with non-string keys - type `dict[typing.Literal['a', 'b'], float]` is not supported

I would think it should be allowed - but Iā€™d like to hear your thoughts.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jcristcommented, Apr 11, 2022

With the new rename config option (https://jcristharif.com/msgspec/structs.html#renaming-field-names) in 0.6.0, this could also be represented as a struct with field names renamed to "1" and "2". For example:

In [1]: import msgspec

In [2]: class ODRaw(msgspec.Struct, rename=lambda f: f[-1:]):
   ...:     """The rename kwarg is used to rename chan_1 to 1 and chan_2 to 2"""
   ...:     chan_1: dict = {}  # Should use your ODReading type instead
   ...:     chan_2: dict = {}
   ...: 

In [3]: decoder = msgspec.json.Decoder(ODRaw)

In [4]: msg = decoder.decode(b'{"1": {"test": "data"}}')  # decoder uses the renamed fields

In [5]: msg
Out[5]: ODRaw(chan_1={'test': 'data'}, chan_2={})

In [6]: msg.chan_1  # Python uses the original field names
Out[6]: {'test': 'data'}

One reason to prefer this over a dict with literal keys is it allows you to mark fields as required, or provide defaults if theyā€™re optional (thereā€™s no way to do this for a dict with literal keys). This should also be a bit faster than decoding a dict with literal keys, but whether that matters is application dependent. No reason to change what you have now if itā€™s working for you, just demonstrating another way this could be handled.

1reaction
CamDavidsonPiloncommented, Feb 28, 2022

šŸ‘

My example does look silly to write this way, but my IRL use case looks like:

PdChannel = Literal["1", "2"]

class ODReadings(Struct):
    timestamp: str
    od_raw: dict[pt.PDChannel, ODReading] 

Because the PdChannels are numbers, I canā€™t use them as keys / attrs!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python "extend" for a dictionary - Stack Overflow
However, I want to point out that many times I have seen the extend method of mapping/set objects desire that in the syntax...
Read more >
PEP 589 ā€“ TypedDict: Type Hints for Dictionaries with a Fixed ...
Let's consider a dictionary object that has exactly two valid string keys, 'name' with value type str , and 'year' with value type...
Read more >
Dictionaries in Python - Real Python
In this Python dictionaries tutorial, you'll cover the basic characteristics and learn how to access and manage dictionary data. Once you have finished...
Read more >
Python List extend() Method (With Examples) - TutorialsTeacher
The extend() method adds all the items from the specified iterable (list, tuple, set, dictionary, string) to the end of the list.
Read more >
Template Designer Documentation - Jinja
A dict or iterable of (key, value) pairs will be joined as a query string. When given a string, ā€œ/ā€ is not quoted....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found