-
-
Notifications
You must be signed in to change notification settings - Fork 366
Return TypedDict instances from Metadata.to_dict() #2099
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Return TypedDict instances from Metadata.to_dict() #2099
Conversation
|
I experimented with making the Making the # src/zarr/abc/metadata.py
...
T = TypeVar("T", bound=dict[str, JSON])
@dataclass(frozen=True)
class Metadata(Generic[T]):
def to_dict(self) -> T:
...However, I ran into issues with the # src/zarr/core/chunk_key_encodings.py
...
class ChunkKeyEncodingDict(TypedDict):
"""A dictionary representing a chunk key encoding configuration."""
name: str
configuration: dict[Literal["separator"], SeparatorLiteral]
@dataclass(frozen=True)
class ChunkKeyEncoding(Metadata[ChunkKeyEncodingDict]): # Type argument "ChunkKeyEncodingDict" of "Metadata" must be a subtype of "dict[str, JSON]"
name: str
separator: SeparatorLiteral = "."It seems like we need a way to bound the Is it possible that this is not supported? Would appreciate any guidance @jhamman @d-v-b |
I think the problem is specifying the type bound to be Second, for some reason Here's an example that I got working: from abc import abstractmethod
from dataclasses import dataclass
from typing import Any, Generic, TypeVar, Mapping, TypedDict
T = TypeVar('T', bound=Mapping[str, object])
class Meta(Generic[T]):
@abstractmethod
def to_dict(self) -> T:
...
class ExampleSpec(TypedDict):
a: str
b: str
@dataclass
class Example(Meta[ExampleSpec]):
a: str
b: str
def to_dict(self) -> ExampleSpec:
return {'a': self.a, 'b': self.b}
x = Example(a='10', b='10')
y = x.to_dict()
reveal_type(y)
"""
Revealed type is "TypedDict('tessel.ExampleSpec', {'a': builtins.str, 'b': builtins.str})"
""" |
26efbff to
0e9ae08
Compare
Define TypedDict classes for metadata models that have a well-typed dict representation and set the return value of the the model's to_dict() method to the TypedDict
Redefine `Metadata` class to be generic and refactor downstream classes
0e9ae08 to
e56547c
Compare
|
Hello @d-v-b! I rebased and pushed commits to make the When you have a moment, a review would be super helpful! |
Summary
This is a
partialimplementation for #1773.So far, I have done the following:
Metadataabc generic overMapping[str, object]TypedDictclasses for the metadata models that have a well-typed dict representationto_dict()method to the relevantTypedDictfrom_dict()methods to the relevantTypedDictCloses #1773
Notes
Metadataabc is generic over a type bound byMapping[str, object]. I haven't been able to getMapping[str, JSON]to work as a type boundTypedDicts for the various Metadata classes were inferred from each respective classes'from_dict(),to_dict(), and initializer methodsfrom_dict()methods utilize a variant of the overloadedparse_named_configurationfunction. This accepts aJSONdata type, causing it to raise a mypy error when called w/ one of theTypedDictclasses. This is the case even if we coerce the TypedDict back to adictbefore calling it. I assume this method is performing runtime validation, so we would not want to substitute it w/ dev-time validation provided by theCodecDictclassesArrayV2Metadata.from_dict()method raise mypy errors due to the theArrayV2MetadataDictbeing coerced to adictto allow it to be mutatedQuestions
from_dict()methods, would it be appropriate to ignore the mypyarg-typeerrors that are raised byparse_named_configuration()? Alternatively,parse_named_configuration()'s signature can be modified to accept aMapping[str, Any]rather thanJSON. This is not equivalent toJSON, but seems to be a sufficient substitute for each place thatparse_named_configurationis currently calledarg-typeerrors in the body ofArrayV2Metadata.from_dict()?node_typeis never found when the dictionaryzgroupis unpacked. However,node_typeis defined w/NotRequired. I searched around and was unable to find any documentation on this -- guidance on next steps would be appreciated!Checklist
TODO: