Getting the next structure hook
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
The issue asks how to chain a pre-normalization step in front of structure hooks, and it mentions get_structure_hook, make_dict_structure_fn, register_structure_hook_factory and use_class_methods. Read how those hooks are resolved and why a generic like list[Foo] raises StructureHandlerNotFoundError, and check the linked attrs issue for the attrib.type string behaviour. Done would be a maintainer-agreed design for field converters running before structuring, with tests for the ensure_list case.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
I am trying to wrap and combine attrs.Converter and the structure hook to have a pre-normalization step before the structure logic kicks in. There are 2 issues I hit
Pre-normalizing the class
Here the issue is that I cannot get the original (or next preferred) structure, roughly can simulate it with
use_class_methods(raw_converter, "from_raw", "to_raw")
@define
class Foo:
a: str
b: int = 1
@classmethod
def from_raw(cls, data, converter):
if isinstance(data, str):
data = {"a": data}
if not isinstance(data, dict):
raise TypeEroor("Unsupported")
original_structure = structure.get_structure_hook(cls)
return original_structure(data, cls)
The recursion here is rather obvious, but there is no way to get n layers further down in the preference to get the next structure hook. Even if it was to be hard-coded or only go one layer further would probably work for most cases.
Pre-normalizing the fields
This is most likely a PEBKAC, but I get StructureHandlerNotFoundError when trying to get the structure hook of a generic. Basically the end goal is to have
@define
class Foo:
a: str
def ensure_list(data):
if not isinstance(data, list):
data = [data]
return data
@define
class Bar:
foo: list[Foo] = field(converter=ensure_list)
@raw_converter.register_structure_hook_factory(has)
def structure_attrs_with_converter(cls, converter):
cls_structure = cattrs.gen.make_dict_structure_fn(
cls,
converter,
**{
attrib.name: override(struct_hook=attr_structure)
for attrib in attrs.fields(cls)
if (
attr_structure := structure_field_with_converter(
attrib=attrib,
converter=converter,
)
)
},
)
return cls_structure
def structure_field_with_converter(attrib, converter):
if not attrib.converter:
return None
original_structure = converter.get_structure_hook(attrib.type)
def structure(raw_value, _type):
value = attrib.converter(raw_value, None, attrib)
return original_structure(value, _type)
return structure
core of the issue here is that attrib.type given here is a str, not even a ForwardRef that I could later evaluate 🤔
Edit: Aha, it's an attrs bug https://github.com/python-attrs/attrs/issues/1596
Also I have tried to get attrs.Converter and cattrs to work nicely together, but so far this is the only way I found feasible. The issue is that the attrs.Converter must run before the main structure of the class, otherwise it will try to structure each element in the foo key before making sure it is a list in this example. If there are other ways to design this, that would be welcome, since this can get a bit messy.
This might be related to https://github.com/python-attrs/cattrs/issues/659?
- Lingua principale
- Python
- Stelle
- 1.1k
- Fork
- 171
- Merge medio
- 14h 46m
- PR unite (30g)
- 5
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di python-attrs/cattrs
-
Dataclass default_factory field treated as required in union disambiguationForse già presa @Eryx-Z l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
python-attrs/cattrs#796 ·
I maintainer di solito rispondono entro 1 giorno
-
decimal.Decimal not handled in preconf converters (json, pyyaml)Forse già presa @Binilkks l’ha presa 114 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
python-attrs/cattrs#761 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
python-attrs/cattrs#513 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Structure hook on a PEP 695 alias is ignored inside a passthrough unionForse già presa @Eryx-Z l’ha presa 2 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 62/100
python-attrs/cattrs#797 ·
I maintainer di solito rispondono entro 1 giorno
-
msgspec converter skips hooks and drops private fields in nested recursionForse già presa @Gabrieljr42 l’ha presa 2 giorni fa. Aperta
Difficoltà 3/5 Mezza giornata Idoneità per principianti 64/100
python-attrs/cattrs#795 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di python-attrs/cattrs
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
webrecorder/warcio#209 ·
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Jeffy123-zhu/logspecter#20 ·
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno