Skip to content

Assinatura do checkpoint não vê mudança fora do repr truncado de um DataFrame no estado de uma condição chamável #299

Open

Description

@bdcdo

Origem: caso que ficou fora do PR #267, anterior a ele.

O que acontece

Um DataFrame do pandas no estado de um objeto chamável usado como condição de field_condition entra na assinatura do checkpoint pelo repr, que o pandas trunca nas primeiras e últimas linhas. Mudar uma linha do meio não muda a assinatura. Na retomada, o checkpoint gravado com uma tabela é aceito com a outra, e as linhas já concluídas ficam com o campo pedido ou pulado pela condição antiga.

Script mínimo, contra ac3ccee7 (Python 3.11.14):

"""DataFrame no estado de um objeto chamável usado em condição."""
import pandas as pd
from pydantic import BaseModel, Field

from dataframeit import field_condition
from dataframeit.core import _run_signature


class Regra:
    def __init__(self, tabela):
        self.tabela = tabela

    def __call__(self, dados):
        return dados.get("tipo") in set(self.tabela["tipo"])


def assinatura(condicao):
    class Pedido(BaseModel):
        tipo: str
        desconto: float | None = Field(
            default=None,
            json_schema_extra=field_condition(condicao, depends_on="tipo"),
        )

    return _run_signature(
        Pedido, "{texto}", provider="p", model="m", model_kwargs=None,
        search_config=None, text_column="texto", status_col="status",
    )[:16]


def tabela(linha_trocada=None):
    df = pd.DataFrame({"tipo": ["vip"] * 100_000})
    if linha_trocada is not None:
        df.loc[linha_trocada, "tipo"] = "ouro"
    return df


base = assinatura(Regra(tabela()))
print("linha 0 trocada, assinatura diferente?", assinatura(Regra(tabela(0))) != base)
print("linha 50000 trocada, assinatura diferente?", assinatura(Regra(tabela(50_000))) != base)

Saída observada:

linha 0 trocada, assinatura diferente? True
linha 50000 trocada, assinatura diferente? False

O que se esperava

As duas linhas com True: a assinatura depende do conteúdo inteiro da tabela.

Causa provável

_instance_state (src/dataframeit/core.py) passa o atributo tabela a _stable com a folha _schema_leaf. O DataFrame não é contêiner que _stable conheça nem chamável que _callable_leaf abra, então volta como está, e o json.dumps de _run_signature o serializa pelo default=_stable_repr, que usa repr(value). Uma folha para DataFrame e Series (por exemplo, pandas.util.hash_pandas_object somado aos nomes e tipos das colunas) daria uma assinatura que depende de todas as células, a custo linear.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions