Skip to content

feat(toolkit): spec 007, adopt the tools-dataset source toolkit - #41

Merged
matbrgz merged 14 commits into
masterfrom
spec-007-tools-dataset
Oct 12, 2026
Merged

matbrgz merged 14 commits into
masterfrom
spec-007-tools-dataset

Conversation

@matbrgz

@matbrgz matbrgz commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Spec 007: o dataset-names passa a usar o kit de fontes benchcommons-tools-dataset 0.1.0 (import datasettool, tag v0.1.0 do tools-dataset) e fica só com o código de nomes.

Refs BenchCommons/tools-dataset#5

Status: Em implementação.

O que mudou

  • Dependência (ADR 0013): benchcommons-tools-dataset==0.1.0 com [tool.uv.sources] git fixado na tag v0.1.0; o uv.lock registra o commit f3251d8. pyyaml e xlrd saem das dependências diretas (o kit os fixa).
  • Adaptadores: namescommons.adapters mantém RawRecord, RawLink e DEFAULT_PACKAGE, reexporta os objetos do kit (AdapterError, FormatError, Resource, SourceFiles, module_name, parse_count, parse_code) e embrulha load_adapter e check_adapter com optional=("links",).
  • Planilhas: o adaptador do INE lê por datasettool.sources.spreadsheet (com a correção do PR fix(spreadsheet): close XLSX DTD pre-scan bypass via declared encodings #39).
  • Cache: o pipeline chama datasettool.sources.cache.fetch_resource com namescommons.USER_AGENT, igual byte a byte ao anterior.
  • Registro: namescommons.sources é um RegistrySchema com os campos de nomes (country, count_type, primary, suppression, uniform_case, strips_accents), as licenças do ADR 0001 (ATTRIBUTION_ONLY_LICENSES + statcan-open-licence) e a regra de uma primary; SourceError é o RegistryError do kit.
  • Manifesto: describe_files do kit com contadores .csv e .parquet.
  • Docs: spec, plano e tarefas em docs/specs/007-tools-dataset/, ADR 0013, nota no status do ADR 0005, AGENTS.md, seção Development do README.md, ROADMAP.md.

Arquivos e testes removidos (substitutos no tools-dataset v0.1.0, 360 testes verdes na tag)

  • src/namescommons/cache.py -> datasettool.sources.cache
  • src/namescommons/spreadsheet.py -> datasettool.sources.spreadsheet
  • tests/test_cache.py (22 testes) -> tests/test_cache.py de lá
  • tests/test_spreadsheet.py -> tests/test_spreadsheet.py de lá; test_r1_3_amostras_do_ine ficou aqui como test_leitor_do_kit_le_as_amostras_do_ine em tests/test_es_ine_residentes.py
  • tests/fixtures/planilhas/tipos.xls -> tests/fixtures/spreadsheets/types.xls de lá (bytes idênticos)
  • tests/test_manifest.py -> tests/test_files.py de lá
  • Testes avulsos (lista exata no plano, seção "Removidos", e nas mensagens de commit): 6 em test_adapters.py, 7 em test_contrato_adaptador.py, 11 mais 3 casos em test_sources.py, 5 mais 1 caso em test_sources_extensoes.py, 1 em test_robustez.py

Critérios de aceite e verificação

  1. uv sync --locked (também na CI) instala o kit da tag; tests/test_tools_dataset.py confere versão, tag, o commit f3251d805f1f7839e59c5472d54833ea7bef840d no uv.lock e o commit_id do pacote instalado (direct_url.json). git ls-remote da tag dá o mesmo commit, e git tag -v v0.1.0 mostra assinatura válida.
  2. cache.py e spreadsheet.py não existem (testes test_namescommons_*_nao_existe); nenhum import yaml em src/.
  3. uv run pytest -q: 586 verdes, sem rede.
  4. Os dois passos offline da CI passam, e diff -r contra master (0153007) não mostra diferença (8 e 109 observações).
  5. namescommons run --offline sobre o cache real completo: 4.336.051 observações, diff -r contra master sem diferença (89 s, 2,84 GB de pico).
  6. tools/bench_pipeline.py --observacoes 200000: OK (1,5 s ingest, 1,3 s build, 261 MB); com --wikidata: OK (1.765 MB).
  7. Lista de remoções acima e no plano.
  8. Checklist de tools-dataset#5 marcado.

Diferenças aceitas (spec, R4.3): mensagens do kit em inglês; ordem das linhas numa mensagem do registro com vários erros (nenhum teste confere ordem); o cache recusa ids e nomes de arquivo inválidos; o manifesto recusa sufixo sem contador.

Decisões tomadas sozinho (com custo se estiverem erradas)

  • Diferença nova encontrada: o cache do kit recusa links simbólicos (cached_path usa resolve()), mesmo com --offline e o arquivo presente. Registrei como item 5 de R4.3, troquei o link simbólico de tools/bench_pipeline.py --wikidata por link físico ou cópia, e abri cache: cached_path refuses symlinked cache entries tools-dataset#9 para o dono decidir. Custo: quem guardava arquivos baixados à mão como link simbólico no cache recebe ValueError até copiá-los.
  • Reexportar os objetos do kit em namescommons.adapters em vez de trocar os imports dos nove adaptadores. Custo: uma camada fina a mais; trocar depois é mecânico.
  • Mensagens de nomes ficam em português, as do kit em inglês, então algumas mensagens misturam as línguas (issue Língua das mensagens de erro depois da adoção do tools-dataset #40). Custo: só texto.
  • parse_count sem invólucro: o campo padrão das mensagens passa de contagem a count. Custo: só texto de erro.
  • SourceError = RegistryError para manter o nome usado pela CLI. Custo: nenhum.
  • Testes de registro com campos de nomes ficaram aqui (o kit testa um espelho com lista fixa de países, não o esquema real com pycountry e strips_accents); saíram só os genéricos. Custo: alguns testes parecidos nos dois repositórios.
  • pyyaml e xlrd fora das dependências diretas. Custo: se um módulo daqui voltar a importá-los, precisa declarar de novo.

Rodada de correções da revisão

  • CI com uv sync --locked (README e AGENTS.md também), teste de test_ci.py atualizado.
  • Commit completo da tag fixado no teste do uv.lock e conferido no pacote instalado.
  • ADR 0013: passo de integridade (git ls-remote da tag contra o uv.lock, git tag -v), constantes VERSAO e COMMIT no procedimento, alinhado com AGENTS.md; consequência sobre o nome não registrado no PyPI (PyPI name benchcommons-tools-dataset is unregistered: reserve it or document uv-only installs tools-dataset#10).
  • pyyaml==6.0.3 no grupo dev, porque os testes importam yaml.
  • Opcional não feito: test_fetch_com_falha_nomeia_a_fonte em tests/test_cli_pipeline.py passa pela CLI (main), que não expõe backoff; o monkeypatch de datasettool.sources.cache.BACKOFF continua sendo o único caminho sem mudar a CLI.

Issues

🤖 Generated with Claude Code

matbrgz and others added 10 commits October 12, 2026 16:21
Spec 007 replaces the local cache, spreadsheet reader, adapter base,
source registry and manifest file helpers with benchcommons-tools-dataset
0.1.0, referencing tools-dataset spec 004 as the owner of the contract.
ADR 0013 records the dependency through a uv git source pinned to the
tag and the upgrade procedure; ADR 0005 points to it.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lists every module and test removed with its replacement in
tools-dataset v0.1.0, the baseline outputs to compare against and the
task order.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Declares the toolkit at ==0.1.0 with a uv git source pinned to tag
v0.1.0 (ADR 0013); uv.lock records commit f3251d8. Tests check the
version, the tag and the installed package.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
namescommons.adapters keeps RawRecord, RawLink and DEFAULT_PACKAGE,
re-exports AdapterError, FormatError, Resource, SourceFiles, module_name,
parse_count and parse_code from datasettool.sources.adapters as the same
objects, and wraps load_adapter and check_adapter with
optional=("links",). Tests that asserted Portuguese messages of the
moved code now assert the toolkit's English messages.

Removed tests, ported to tools-dataset tests/test_adapters.py:
test_adapters.py: test_nome_do_modulo, test_carrega_o_adaptador_de_exemplo,
test_adaptador_inexistente, test_adaptador_valido, test_adaptador_invalido,
test_adaptador_sem_atributo; test_contrato_adaptador.py:
test_r2_2_parse_count, test_r2_2_parse_count_recusa_o_que_nao_conhece,
test_r2_2_parse_code_traduz_e_recusa_codigo_desconhecido,
test_r2_6_arquivo_fora_de_resources_lista_os_disponiveis,
test_r2_6_adaptador_ausente_mostra_o_caminho_esperado,
test_r2_6_adaptador_quebrado_nao_se_passa_por_ausente,
test_r2_6_pacote_de_adaptadores_inexistente.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The INE adapter reads XLS and XLSX through
datasettool.sources.spreadsheet, which carries the PR #39 hardening.
xlrd is no longer a direct dependency; the toolkit pins it at 2.0.2.

Removed, ported to tools-dataset at v0.1.0:
- src/namescommons/spreadsheet.py (datasettool.sources.spreadsheet)
- tests/test_spreadsheet.py (tests/test_spreadsheet.py there); its
  test_r1_3_amostras_do_ine stays here as
  test_leitor_do_kit_le_as_amostras_do_ine with the same vectors
- tests/fixtures/planilhas/tipos.xls (byte-identical
  tests/fixtures/spreadsheets/types.xls there)

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…gent

The pipeline calls datasettool.sources.cache.fetch_resource with
namescommons.USER_AGENT, built by make_user_agent and equal byte for
byte to the old header. Retry options use the toolkit names (attempts,
backoff, sleep). tools/amostra_wikidata.py imports USER_AGENT from
namescommons.

The toolkit refuses cache entries that resolve outside the cache, which
includes symlinks: tools/bench_pipeline.py --wikidata now hard-links (or
copies) the files instead of symlinking the directory. Spec 007 R4.3
records the difference; the decision is tracked in
BenchCommons/tools-dataset#9.

Removed, ported to tools-dataset at v0.1.0:
- src/namescommons/cache.py (datasettool.sources.cache)
- tests/test_cache.py, 22 tests (tests/test_cache.py there, 28)

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
namescommons.sources declares a RegistrySchema with the names fields
(country, count_type, primary, suppression, and the optional
uniform_case and strips_accents), the ADR 0001 licence list (the
toolkit's ATTRIBUTION_ONLY_LICENSES plus statcan-open-licence) and the
one-primary rule as a cross-entry check; the factory builds the same
Source dataclass. load_sources and parse_sources keep their signatures,
and SourceError is the toolkit's RegistryError. Names field messages
stay in Portuguese. pyyaml is no longer a direct dependency.

Removed tests, ported to tools-dataset tests/test_registry.py:
test_sources.py: test_arquivo_sem_fontes, test_id_com_formato_invalido,
test_campo_ausente (replaced here by test_campo_de_nomes_ausente),
test_id_duplicado, test_licenca_nao_textual_vira_source_error,
test_id_nao_textual_vira_source_error, test_entrada_que_nao_e_mapeamento,
test_arquivo_inexistente, test_yaml_malformado,
test_raiz_que_nao_e_mapeamento, test_sources_que_nao_e_lista and the
retrieved, url and extra cases of test_campo_invalido;
test_sources_extensoes.py: test_retrieved_com_hora_e_recusado,
test_retrieved_com_hora_no_yaml_e_recusado,
test_url_sem_esquema_http_e_recusada, test_url_http_e_https_aceitas,
test_url_malformada_nomeia_a_fonte_em_vez_de_levantar_value_error and
the adapter case of test_campo_opcional_nao_booleano.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
build_manifest keeps the release format, schema_version and the sources
list, and takes the files map from describe_files with counters for
.csv (the toolkit's count_csv_records) and .parquet (Parquet metadata).
An output file with another suffix is now a ValueError instead of being
counted as CSV; the outputs only have .csv and .parquet.

Removed, ported to tools-dataset tests/test_files.py:
- tests/test_manifest.py (1 test, 6 cases)
- test_robustez.py: test_manifesto_conta_registros_csv_e_nao_linhas_fisicas

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AGENTS.md describes the toolkit in the stack and the upgrade steps,
README gains a Development section, and spec 007 tasks record the
verification: identical outputs on the fixtures and on the full real
cache, and the small benchmark run.

Refs BenchCommons/tools-dataset#5

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
matbrgz and others added 2 commits October 12, 2026 16:41
Spec 007 acceptance criterion 1 requires the locked install: CI now runs
uv sync --locked, so a uv.lock out of sync with pyproject.toml (for
example a changed toolkit tag) fails the build. README and AGENTS.md use
the same command.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
test_uv_lock_aponta_a_tag now asserts the full commit of tag v0.1.0
(f3251d805f1f7839e59c5472d54833ea7bef840d), and
test_kit_instalado_do_commit_da_tag checks the installed distribution's
direct_url.json vcs_info.commit_id against it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
matbrgz and others added 2 commits October 12, 2026 16:42
The upgrade procedure gains an integrity step (git ls-remote of the
peeled tag must match the commit in uv.lock and in the COMMIT test
constant; git tag -v must show a valid signature) and updates the test
constants together with pyproject.toml, aligned with AGENTS.md. Checked
for v0.1.0: f3251d8, good signature. The consequences note that
non-uv installers would look the name up on PyPI, where it is not
registered (BenchCommons/tools-dataset#10).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tests import yaml directly (CI workflow and registry checks); pin it in
the dev group at the toolkit's version instead of relying on the
transitive dependency.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@matbrgz
matbrgz merged commit 4cb2c5f into master Oct 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant