Repository navigation
Conversation
…retomada O reconhecimento de estrutura passa a ser por issubclass contra as ABCs Sequence, Set e Mapping, menos texto e bytes, o que inclui o deque de collections e o typing.Deque. O checkpoint o grava em JSON, também dentro de outra estrutura, e a retomada o devolve como deque nos três formatos. Closes #287
EvidênciaScript: a função Na base (
|
| Caso | Esperado | Obtido no ramo |
|---|---|---|
deque[str] em csv, xlsx, parquet |
volta deque, retomada chama só ['b'] |
igual, nos três |
typing.Deque[str] em csv, xlsx, parquet |
idem | igual, nos três |
dict[str, deque[str]] em csv, xlsx, parquet |
o deque de dentro volta deque |
igual (na base, recusado nos três) |
Counter, OrderedDict, defaultdict em csv, xlsx, parquet |
tipo e valor gravados, só ['b'] |
igual (já na base) |
is_complex_type de deque, Deque, Counter, OrderedDict, defaultdict, DefaultDict |
True | True |
is_complex_type de bytes, bytearray, StrEnum, Literal |
False | False |
Mutação: tirar de _json_default o ramo que converte a sequência em lista deixa vermelhos os 9 casos de deque do teste de retomada (3 modelos x 3 formatos), e os 30 outros passam.
Testes
| Passados | Pulados | Falhas | |
|---|---|---|---|
| base | 2192 | 0 | 0 |
| ramo | 2219 | 0 | 0 |
Os 27 novos: 18 da retomada (6 modelos x 3 formatos) e 9 de is_complex_type. Cobertura de ramo local de 99,96% na base e no ramo, com as mesmas linhas 723-724 de codex.py descobertas, efeito do extra codex instalado; as linhas tocadas estão cobertas. ruff format --check, ruff check, ty check, vulture e deptry src passam.
Risco: médio, porque o critério de estrutura passa a ser por ABC e vale para toda coluna de objeto que o CSV e o XLSX gravam; desfaz-se com o revert do squash.
SHA revisado: 2a05419
… no JSON do checkpoint
# Conflicts: # CHANGELOG.md
|
Rodada 2, pela revisão independente do head Achado importante corrigido. Com uma coluna do usuário de
Testes novos, todos reprovam no head
Com o Execução neste head, antes do merge da Nits da revisão que ficaram como estão. Risco: médio. Para desfazer, basta o revert do squash. SHA revisado: |
Problema
Um campo
deque[str]não entrava emget_complex_fields, porque_STRUCTURE_CLASSESlistava classes concretas e odequenão é subclasse de nenhuma delas. Omodel_dumpdevolve o própriodeque, e o checkpoint não o gravava em JSON: o CSV e o XLSX gravavam o repr, e a retomada recusava a linha concluída pedindoreprocess_columns=['obs']; o parquet não conseguia gravar a coluna (ArrowInvalid: Could not convert deque(['a', 'z'])), e a retomada pagava de novo as linhas concluídas.O que muda
is_complex_typereconhece a estrutura porissubclasscontra as ABCsSequence,SeteMapping, menosstr,bytesebytearray(inclusive oStrEnum), além do modelo Pydantic. Isso cobre o que já era reconhecido (lista, tupla,NamedTuple, conjunto, dict,TypedDict, as origens abstratas e as mutáveis) e acrescenta odeque, decollectionsoutyping.Deque. A lista de classes concretas e a busca por identidade das origens abstratas saem._json_defaultgrava a sequência que não é lista nem tupla, como odeque, como lista. Isso vale também para odequedentro de outra estrutura, comodict[str, deque[str]], e para a comparação da retomada (_same_json), que reconhece o valor relido como o mesmo e devolve odeque._structures_as_jsonusa o mesmo critério para decidir o que vai a JSON no checkpoint.get_complex_fieldsinclui odeque.As outras coleções que o pydantic aceita
Medido com a função
comparada issue, sobre csv, xlsx e parquet (Python 3.11.14, pydantic 2.14.2, pandas 3.1.0, pyarrow 26.0.0):maincollections.deque[str],typing.Deque[str]['a', 'b']deque, chama só['b']nos trêsdict[str, deque[str]]dequedentroCounter[str],typing.Counter[str]Counter, chama só['b']OrderedDict[str, int],typing.OrderedDictOrderedDictdefaultdict[str, int],typing.DefaultDictmodel_dumpdevolvedict, que voltadictMutableSequence[str],Sequence[str]Collection[str],Iterator[str],ChainMap,UserListPydanticSchemaGenerationError)Iterable[str],Generator[str, None, None]O pydantic aceita
IterableeGenerator, mas valida de forma preguiçosa: omodel_dumpdevolve umSerializationIterator, e a saída direta, sem checkpoint, já traz esse objeto na célula, e não a lista respondida. O defeito está na execução, antes do checkpoint, e tratar esses campos como estrutura não o resolve. Ficam fora deste PR e merecem issue própria, que decida entre recusar a anotação antes de processar ou materializar o valor em lista.Closes #287