From 505a72c77af59c32786650b5b5d4fd81202f8685 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 23:44:06 +0000 Subject: [PATCH 1/4] chore(deps): bump astral-sh/setup-uv from 10.2.0 to 10.3.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/v10.2.0...v10.3.0) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 10.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- .github/workflows/tests.yml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4ee4b013..69332808 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -33,7 +33,7 @@ jobs: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 89478015..4bbfd525 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -60,7 +60,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -118,7 +118,7 @@ jobs: python-version: '3.11' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -150,7 +150,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -184,7 +184,7 @@ jobs: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -210,7 +210,7 @@ jobs: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true @@ -232,7 +232,7 @@ jobs: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@v10.3.0 with: enable-cache: true From c05841941cc1bbbedab2f06ce9922b7aa86b5abc Mon Sep 17 00:00:00 2001 From: Bruno da Cunha de Oliveira Date: Sat, 24 Oct 2026 03:54:29 -0300 Subject: [PATCH 2/4] fix: avoid deprecated pandas chained-assignment option --- CHANGELOG.md | 2 ++ src/dataframeit/core.py | 25 ++++++++++++------------- tests/test_regressions.py | 2 ++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4c28b0..08a0bf1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR ### Corrigido +- A criação das colunas de saída não altera a opção global `mode.chained_assignment`, removida do fluxo para não emitir aviso de depreciação no pandas 3.1 (#269). + - No provider `codex`, a thread daemon que pede o `thread/unsubscribe` da linha abortada pela morte do app-server deixa de ficar presa para sempre. O processo morto ainda aceita a escrita enquanto termina, e o SDK registra a espera da resposta depois de o leitor do stdout ter acordado os pedidos em voo; agora o fechamento do cliente acorda essa espera (#250). - `read_df` com argumento de leitura que faz o pandas devolver outra coisa que um DataFrame, como `chunksize`, `iterator`, `sheet_name=None` ou lista e o `chunksize` do JSON em linhas, devolve o `TextFileReader`, o `JsonReader` ou o dict de abas como o pandas o devolve, sem normalizar, com ou sem modelo. Antes, sem modelo, ou com modelo que tem campo de lista, dict ou modelo aninhado, e com `normalize=True`, o padrão, a função levantava `AttributeError` ao procurar as colunas no objeto do leitor (#249). - Com entrada polars, a saída deixa de trocar sem aviso o valor que o modelo devolveu quando o pyarrow tipa a coluna pelo primeiro valor e converte os demais. Sai `Object`, com o aviso das colunas que o polars não reúne, o campo cuja anotação junta `timedelta` a outro tipo, `float` a `bool` ou `bytes` a `str`, e a coluna cujos valores trazem essas combinações ou as de data e hora, também em `Any`, onde o escalar do numpy, como o `np.int64`, conta como o número do Python, nos itens de lista e no campo de modelo aninhado, além da coluna cujos dicts do mesmo campo têm chaves diferentes e da que traz `datetime` com e sem fuso, `time` com fuso ou `Decimal` NaN. O NaN de campo `float` sai NaN. Antes, em `Union[timedelta, int]` o 5 virava cinco microssegundos, em `Union[float, bool]` o `True` virava `1.0`, o `datetime` sem fuso ganhava o fuso do primeiro, o `time` perdia o fuso, o `Decimal` NaN e o NaN de campo `float` viravam nulo, `{}` ao lado de `{"a": 1}` virava `{"a": None}`, e em `Union[NewType sobre date, int]` o 5 virava `1970-01-06`. Com `resume=True`, a coluna do campo cuja anotação é `int`, um `Literal` com inteiro ou uma união com um deles é lida com os inteiros do polars, e o inteiro acima de 2**53 deixa de voltar arredondado em `Float64`. O `Decimal` NaN e o NaN de campo `float` de uma linha processada deixam de ser acusados como incompatíveis na retomada, também com entrada pandas, e o reprocessamento campo a campo os repassa às condições como valor; na coluna float64, como a do checkpoint relido, o NaN não se distingue do nulo e segue contando como ausente. O `NewType` e o apelido `type`, inclusive o apelido genérico usado com argumentos, como `Opcional[int]` de `type Opcional[T] = T | None`, passam a contar pelo tipo a que se referem na saída polars, na retomada e em `read_df`: o `NewType` sobre `dict` sai em texto JSON, como o campo `dict`, e é retomado, e o campo `NewType` sobre `str` ou sobre `int` é relido do CSV como texto cru ou como inteiro exato (#241). diff --git a/src/dataframeit/core.py b/src/dataframeit/core.py index 09019e12..e720069d 100644 --- a/src/dataframeit/core.py +++ b/src/dataframeit/core.py @@ -1723,20 +1723,19 @@ def _setup_columns( # noqa: C901, PLR0912, PLR0913 (uma família de colunas por return # Criar colunas - with pd.option_context("mode.chained_assignment", None): - for col in new_cols: - df[col] = None - if needs_status: - df[status_col] = None - if needs_error: - df[error_col] = None - if track_tokens: - for col in needs_tokens: - df[col] = None - for col in needs_search: - df[col] = None - for col in needs_trace: + for col in new_cols: + df[col] = None + if needs_status: + df[status_col] = None + if needs_error: + df[error_col] = None + if track_tokens: + for col in needs_tokens: df[col] = None + for col in needs_search: + df[col] = None + for col in needs_trace: + df[col] = None def _get_processing_indices( diff --git a/tests/test_regressions.py b/tests/test_regressions.py index 8568bfd6..3b8f1fe2 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -1,9 +1,11 @@ import pandas as pd +import pytest from dataframeit import llm as llm_module from dataframeit.core import _setup_columns +@pytest.mark.filterwarnings("error") def test_setup_columns_mutates_independent_copy_only(): df = pd.DataFrame( { From fa7e00cf2ca8376839a9aa188cdacd715f46cf18 Mon Sep 17 00:00:00 2001 From: Bruno da Cunha de Oliveira Date: Sat, 24 Oct 2026 03:56:55 -0300 Subject: [PATCH 3/4] fix: preserve sliced-input behavior on pandas 2 --- CHANGELOG.md | 2 +- src/dataframeit/core.py | 35 +++++++++++++++++++++-------------- tests/test_regressions.py | 7 +++++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08a0bf1e..ee92f42d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR ### Corrigido -- A criação das colunas de saída não altera a opção global `mode.chained_assignment`, removida do fluxo para não emitir aviso de depreciação no pandas 3.1 (#269). +- A criação das colunas de saída usa a opção `mode.chained_assignment` só no pandas 2, preservando entradas fatiadas sem emitir aviso de depreciação no pandas 3.1 (#269). - No provider `codex`, a thread daemon que pede o `thread/unsubscribe` da linha abortada pela morte do app-server deixa de ficar presa para sempre. O processo morto ainda aceita a escrita enquanto termina, e o SDK registra a espera da resposta depois de o leitor do stdout ter acordado os pedidos em voo; agora o fechamento do cliente acorda essa espera (#250). - `read_df` com argumento de leitura que faz o pandas devolver outra coisa que um DataFrame, como `chunksize`, `iterator`, `sheet_name=None` ou lista e o `chunksize` do JSON em linhas, devolve o `TextFileReader`, o `JsonReader` ou o dict de abas como o pandas o devolve, sem normalizar, com ou sem modelo. Antes, sem modelo, ou com modelo que tem campo de lista, dict ou modelo aninhado, e com `normalize=True`, o padrão, a função levantava `AttributeError` ao procurar as colunas no objeto do leitor (#249). diff --git a/src/dataframeit/core.py b/src/dataframeit/core.py index e720069d..5a9e243f 100644 --- a/src/dataframeit/core.py +++ b/src/dataframeit/core.py @@ -15,7 +15,7 @@ import time import warnings from concurrent.futures import ThreadPoolExecutor, as_completed -from contextlib import contextmanager +from contextlib import contextmanager, nullcontext from dataclasses import dataclass from decimal import Decimal from enum import Enum @@ -1722,20 +1722,27 @@ def _setup_columns( # noqa: C901, PLR0912, PLR0913 (uma família de colunas por ): return - # Criar colunas - for col in new_cols: - df[col] = None - if needs_status: - df[status_col] = None - if needs_error: - df[error_col] = None - if track_tokens: - for col in needs_tokens: + # O pandas 2 ainda avisa ao escrever numa fatia; no pandas 3, a cópia na + # escrita substitui esse aviso e a opção que o controla não se aplica. + context = ( + pd.option_context("mode.chained_assignment", None) + if hasattr(pd.errors, "SettingWithCopyWarning") + else nullcontext() + ) + with context: + for col in new_cols: + df[col] = None + if needs_status: + df[status_col] = None + if needs_error: + df[error_col] = None + if track_tokens: + for col in needs_tokens: + df[col] = None + for col in needs_search: + df[col] = None + for col in needs_trace: df[col] = None - for col in needs_search: - df[col] = None - for col in needs_trace: - df[col] = None def _get_processing_indices( diff --git a/tests/test_regressions.py b/tests/test_regressions.py index 3b8f1fe2..fbfa7a22 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -6,14 +6,17 @@ @pytest.mark.filterwarnings("error") -def test_setup_columns_mutates_independent_copy_only(): +@pytest.mark.parametrize("copy_input", [False, True]) +def test_setup_columns_mutates_slice_without_warnings(copy_input): df = pd.DataFrame( { "texto": ["a", "b", "c"], "x": [1, 2, 3], } ) - df_copy = df.iloc[:2].copy() + df_copy = df.iloc[:2] + if copy_input: + df_copy = df_copy.copy() _setup_columns( df_copy, From 068d674def0715274b5aeee7cb2db59ab6c6d762 Mon Sep 17 00:00:00 2001 From: Bruno da Cunha de Oliveira Date: Sat, 24 Oct 2026 03:59:31 -0300 Subject: [PATCH 4/4] test: cover both pandas compatibility paths --- tests/test_regressions.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_regressions.py b/tests/test_regressions.py index fbfa7a22..91919ee1 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -1,3 +1,5 @@ +from contextlib import nullcontext + import pandas as pd import pytest @@ -57,3 +59,24 @@ def test_build_prompt_preserves_other_placeholders(): assert "TEXTO" in formatted assert "{texto}" not in formatted assert "{outro}" in formatted # Preserva outros placeholders + + +@pytest.mark.parametrize("legacy_warning", [False, True]) +def test_setup_columns_uses_option_only_with_legacy_warning(monkeypatch, legacy_warning): + calls = [] + + def option_context(*args): + calls.append(args) + return nullcontext() + + monkeypatch.setattr(pd, "option_context", option_context) + if legacy_warning: + monkeypatch.setattr(pd.errors, "SettingWithCopyWarning", UserWarning, raising=False) + else: + monkeypatch.delattr(pd.errors, "SettingWithCopyWarning", raising=False) + + df = pd.DataFrame({"texto": ["a"]}) + _setup_columns(df, ["resposta"], None, track_tokens=False) + + assert calls == ([("mode.chained_assignment", None)] if legacy_warning else []) + assert df["resposta"].isna().all()