Skip to main content

nini-datacomp

PyPI Python CI Licença

Compara duas tabelas grandes linha a linha, dentro de um orçamento de memória. Diz quais linhas existem só de um lado, quais divergem, em que colunas e com exemplos, num relatório em texto, Markdown, HTML ou JSON.

É a reescrita do datacompolars: o mesmo resultado (os testes conferem os casos de borda contra ele, amostra por amostra), com a comparação em kernels C++ que leem as colunas do Polars sem cópia.

  • Memória sob controle: a comparação anda em janelas pela chave, do tamanho que cabe no memory_limit ("auto" = 1/4 da RAM livre, até 2 GB). Tabelas maiores que a memória são comparadas sem problema.
  • Rápida: 10 milhões de linhas x 300 colunas em 32 s com 1 GB, onde o datacompolars levava 50 s e usava quase 2 GB (números).
  • Sem surpresas: igualdade exata pelo hash de linha (com verify_hash=True para conferir célula a célula), tolerâncias absolutas e relativas com a aritmética do Polars, texto sem caixa e sem espaços, nulos e NaN como no datacompolars.
  • Lê o que você tem: Parquet, CSV, JSON, Arrow, Avro, Excel e os arquivos do SAS (.sas7bdat, .xpt), do Stata (.dta) e do SPSS (.sav, .zsav, .por), estes pelo ReadStat compilado na própria biblioteca: nenhum pacote a mais.
  • Leve: só polars, numpy e pydantic; wheels prontos para Linux, Windows e macOS (x86-64 e ARM), sem compilador.

Instalação

pip install nini-datacomp

Python 3.10 ou mais novo e Polars 1.30 ou mais novo.

Uso

import nini_datacomp as dc  # importe antes do Polars (veja Memória)

result = dc.compare(
    "sas/tops_adm.parquet",  # arquivo, pasta, glob, pl.DataFrame ou pl.LazyFrame
    "lake/tops_adm/",
    on=["id", "competencia"],  # a chave: uma coluna ou várias
    abs_tol={"valor": 0.005},  # tolerância numa coluna (ou um número para todas)
    memory_limit="2GB",
)

result.is_match  # False
result.rows.mismatched  # linhas em comum com algum valor diferente
result.columns["valor"].mismatches  # divergências nessa coluna
result.columns["valor"].samples  # pl.DataFrame: id, competencia, valor (left), valor (right)

print(result.report())  # o relatório em texto
result.report(path="relatorio.html")  # ou em HTML (o formato sai da extensão)

As opções vão como argumentos nomeados, como acima, ou num dc.CompareOptions(...) passado em options=.

Formatos

O formato sai da extensão; uma pasta vira uma fonte só (com as subpastas; arquivos que começam com . ou _ ficam de fora). Tudo o que não é Parquet é convertido uma vez para Parquet numa pasta temporária, aos pedaços (cada um com ~1/16 do memory_limit), e a pasta some no fim da comparação.

formato extensões como é lido
Parquet .parquet, .pq direto
CSV .csv, .tsv aos pedaços (pl.scan_csv); outra codificação é convertida para UTF-8 antes
NDJSON, Arrow IPC .ndjson, .jsonl, .arrow, .ipc, .feather aos pedaços
JSON, Avro .json, .avro inteiro na memória (o Polars só lê assim)
Excel .xlsx, .xlsm, .xlsb, .xls, .ods inteiro; precisa do pacote fastexcel
SAS .sas7bdat, .xpt aos pedaços, pelo ReadStat
Stata .dta idem
SPSS .sav, .zsav, .por idem

read=dc.ReadOptions(...) muda a leitura, para os dois lados ou um par (esquerda, direita):

dc.compare(
    "sas/tops_adm.sas7bdat",
    "lake/tops_adm/",
    on="id",
    cast="right",  # no SAS todo número é real (Float64); no lake o id costuma ser inteiro
    read=(dc.ReadOptions(encoding="wlatin1"), dc.ReadOptions()),
)
opção padrão o que faz
format pela extensão força o formato ("csv", "sas", ...)
encoding do arquivo CSV: a codificação ("latin1", "cp1252"); SAS/Stata/SPSS: no lugar da que o arquivo declara (o .xpt não declara); aceita os nomes do SAS ("wlatin1")
blank_strings_as_null True SAS/Stata/SPSS: texto vazio vira nulo, que é como o SAS grava texto ausente
convert_dates True SAS/Stata/SPSS: colunas com formato de data, data e hora ou hora (DATE9., DATETIME20., %td, ADATE10...) viram Date, Datetime("us") e Time
separator, has_header, decimal_comma, null_values CSV padrão CSV (.tsv usa tabulação)
infer_schema_length, schema_overrides 10.000 linhas CSV/JSON/Excel: como deduzir os tipos, ou os tipos de algumas colunas
sheet a primeira Excel: nome ou número da planilha
csv_options {} CSV: outros argumentos de pl.scan_csv
recursive True pasta: procura também nas subpastas
temp_dir o do sistema onde fica o Parquet temporário

Para ler fora da comparação: dc.read_sas, dc.read_stata e dc.read_spss devolvem um pl.DataFrame; dc.scan_sas, dc.scan_stata e dc.scan_spss, um pl.LazyFrame lido aos pedaços quando a consulta roda (cada collect lê o arquivo de novo).

O resultado

atributo o que traz
is_match os dois lados são iguais: mesmas linhas, mesmos valores, mesmas colunas e tipos
rows left_total, right_total, common, left_only, right_only, mismatched, matched, mismatch_rate
columns mapeamento por nome das colunas comparadas (dtype, mismatches, rate, samples, tolerance), mais left_only, right_only, type_mismatches e mismatched() (da que mais diverge para a que menos)
errors, aborted erros fatais (chave que falta, chave de tipos diferentes, chave repetida): ficam aqui, sem exceção
warnings avisos (nenhuma coluna além da chave, tolerância para uma coluna que não existe)
execution janelas, grupos de colunas, memória, tempo por etapa, versões
report(...), to_dict(), to_json() o relatório e a forma serializável

O relatório

result.report(format=None, path=None, *, width=100, style="auto", max_columns=20, max_sample_columns=10, print_output=False), nos formatos "text", "markdown", "html" e "json". Sem format, o formato sai da extensão de path (.md, .html, .json, .txt); com path, o relatório também é salvo. Texto e Markdown mostram até max_columns colunas com divergência; HTML e JSON trazem tudo.

┌──────────────────────────────────────────────────────────────────────────────┐
│ ✘ DIFFERENCES FOUND                                                          │
│ 2 of 3 common rows differ (66.67%); 1 rows only in sas; 1 rows only in lake. │
└──────────────────────────────────────────────────────────────────────────────┘

DIFFERENCES BY COLUMN
─────────────────────

  ┌────────┬─────────┬─────────────┬─────────────┬──────────────┐
  │ Column │ Type    │ Differences │ % of common │              │
  ├────────┼─────────┼─────────────┼─────────────┼──────────────┤
  │ valor  │ Float64 │           2 │      66.67% │ ████████░░░░ │
  └────────┴─────────┴─────────────┴─────────────┴──────────────┘

SAMPLE DIFFERING ROWS
─────────────────────

  valor: 2 differing rows, showing 2
  ┌────┬─────────────┬─────────────┬──────────────┐
  │ id │ competencia │ valor (sas) │ valor (lake) │
  ├────┼─────────────┼─────────────┼──────────────┤
  │ 2  │ 2026-01     │ 10          │ 10.5         │
  │ 3  │ 2026-01     │ 7.25        │ null         │
  └────┴─────────────┴─────────────┴──────────────┘

Opções

opção padrão o que faz
names ("left", "right") os rótulos dos dois lados nas amostras e no relatório
case_sensitive_columns False False: os nomes das colunas são comparados em minúsculas
cast "none" colunas de tipos diferentes: "left" converte a direita, "right" a esquerda, "none" só as lista
abs_tol, rel_tol 0.0 tolerâncias nas colunas numéricas (um número ou um por coluna): igual se |l - r| <= abs_tol + rel_tol * |r|
ignore_whitespace, ignore_case False texto comparado sem espaços em branco e/ou em minúsculas
details True divergências por coluna e amostras (False: só as contagens de linhas)
samples 5 linhas divergentes guardadas por coluna, na ordem da chave
memory_limit "auto" orçamento de memória: bytes ou texto ("512MB", "2GB", "1.5GiB")
window_rows None avançado: linhas por janela, no lugar do cálculo pelo memory_limit
threads None threads dos kernels C++ (padrão: todos os núcleos)
verify_hash False confere as colunas exatas célula a célula em todos os pares, além do hash
unordered_lists () colunas List comparadas sem a ordem dos elementos ([1, 2] = [2, 1])
comparators {} comparador próprio por coluna (veja Comparadores próprios)
only_common_keys False tabelas com faixas de chave muito diferentes: só a faixa que os dois lados têm é lida por inteiro; o resto só é contado (mesmo resultado)
read ReadOptions() como ler os arquivos (veja Formatos)

Uma opção com nome errado é erro (extra="forbid"), em vez de ser ignorada.

Comparadores próprios

comparators={"coluna": ...} troca a comparação de uma coluna (a chave não pode). A regra de nulos é a de sempre: nulo com nulo é igual, nulo de um lado só é diferente, e o comparador só decide os pares sem nulo. Tolerâncias e as opções de texto não se aplicam à coluna: quem decide é o comparador.

O caminho rápido é o dc.expr, uma mini-linguagem que roda nos kernels C++:

from nini_datacomp.expr import left, right

dc.compare(
    a,
    b,
    on="id",
    comparators={
        "nome": left.strip().lower() == right.strip().lower(),
        "valor": (left - right).abs() <= 0.01 * right.abs(),
        "codigo": left.remove_whitespace() == right.remove_whitespace(),
    },
)

Tem + - * /, abs(), == != < <= > >=, & | ~ e, no texto, lower(), upper(), strip(), remove_whitespace() e len(), com a semântica do Polars (inclusive o Unicode: "ß".upper() == "SS"). Lê inteiros (menos UInt64), reais, booleanos e texto; reais fazem conta em 64 bits.

Para o resto, uma função f(esquerda, direita) -> pl.Expr (ou um comparador do datacompolars, com compare), que roda no Polars só nos pares daquela coluna e avisa com PerformanceWarning:

comparators = {"itens": lambda l, r: l.list.sort() == r.list.sort()}

Tipos

Inteiros, reais, booleano, texto (String, e Categorical e Enum comparados como texto), Date, Datetime, Duration, Time e Decimal, e os aninhados (List, Array e Struct), comparados pelo valor inteiro: [1, 2] e [2, 1] são diferentes, a não ser que a coluna esteja em unordered_lists; tolerâncias e as opções de texto não entram nos campos de dentro. Os aninhados vão pelo hash do valor (o Expr.hash do Polars, 64 bits), como as outras colunas exatas.

Desempenho

O caminho exato (hash de linha) contra o datacompolars 0.4.4, com memory_limit="1GB" (954 MiB), num Windows 11 com 16 threads e 15,7 GB. Média de 5 execuções, cada uma num processo novo; a razão vem com o IC de 95%, e um caso é ok se o intervalo inteiro fica em até 1,10. As contagens (linhas e divergências por coluna) conferem em todos.

linhas x colunas nini-datacomp pico datacompolars pico razão (IC 95%)
1M x 10 0,11 s 406 MiB 0,22 s 698 MiB 0,51 (0,46–0,56)
1M x 50 0,37 s 682 MiB 0,43 s 1070 MiB 0,85 (0,82–0,89)
1M x 300 3,20 s 561 MiB 3,35 s 1709 MiB 0,95 (0,85–1,06)
10M x 10 0,76 s 734 MiB 1,16 s 1631 MiB 0,66 (0,63–0,68)
10M x 50 4,77 s 633 MiB 4,26 s 1679 MiB 1,12 (0,98–1,26), inconclusivo
10M x 300 31,9 s 674 MiB 50,0 s 1929 MiB 0,64 (0,62–0,65)

O nini-datacomp fica dentro do memory_limit em todos os casos; o datacompolars não tem orçamento e usa até o dobro. Os detalhes, com o caminho coluna a coluna (com tolerância), estão em docs/benchmarks/.

Memória

Importe o nini_datacomp antes do Polars. No import, ele configura o alocador do Polars (MIMALLOC_PURGE_DELAY=10 e MIMALLOC_RESET_DELAY=10) para devolver em 10 ms a memória que libera: sem isso, numa comparação grande no Windows o pico chega a ~1,9x; devolvendo na hora, cada janela pede de novo ao sistema a memória da anterior (até ~30% mais lento). Se o Polars já tiver sido importado, não dá mais para configurar e o pacote avisa com AllocatorWarning; dá para definir as variáveis antes de iniciar o Python, ou silenciar com NINI_DATACOMP_ALLOCATOR=0.

Vindo do datacompolars

Mesma semântica; mudam os nomes, e o que era ajuste interno do motor vira um orçamento de memória.

datacompolars 0.4.4 nini-datacomp observação
compare(left, right, settings) compare(left, right, on=..., options=...) on sai das opções; opções também como argumentos nomeados
CompareSettings CompareOptions pydantic, extra="forbid" (nome errado é erro)
join_columns on uma coluna (texto) ou várias
left_name, right_name names=("left", "right")
lowercase_columns=True case_sensitive_columns=False mesmo padrão, nome positivo
casting cast "none", "left" ou "right"
abs_tol, rel_tol abs_tol, rel_tol número ou um por coluna (dict)
ignore_spaces, ignore_case ignore_whitespace, ignore_case
check_duplicate_keys — chave repetida sempre aborta (a checagem não custa nada)
column_details, sample_count details, samples
window_rows, cache_windows, prefetch_windows, columns_per_batch memory_limit="auto" (+ window_rows) o motor escolhe janelas e grupos de colunas pelo orçamento; "auto" = 1/4 da RAM livre, até 2 GB
— threads, verify_hash threads dos kernels C++; conferir o hash de linha célula a célula
common_keys_only only_common_keys mesmo resultado, só mais barato com faixas de chave muito diferentes
List comparada sem ordem (sempre) unordered_lists=[...] muda o padrão: as listas são comparadas com a ordem, a não ser as de unordered_lists
custom_comparators comparators dc.expr no C++; funções do Polars e os comparadores do datacompolars continuam valendo, com PerformanceWarning
SourceOptions read=ReadOptions(...) também um por lado; o SAS sem o extra [sas] (o ReadStat vem compilado)
result.fatal_errors result.errors
result.column_stats result.columns.mismatched() mesma ordem: da coluna que mais diverge para a que menos
result.samples (lista de SampleTable) result.columns["c"].samples pl.DataFrame, mesmos cabeçalhos
result.columns.compared result.columns.compared result.columns também é um mapeamento por nome
result.report(ReportSettings(...)) result.report(format=None, path=None, width=100, ...) os mesmos 4 formatos; não imprime sozinho (print_output=True imprime)
result.to_json(), model_dump() result.to_json(), result.to_dict() o resultado é uma dataclass, não pydantic

Desenvolvimento

Precisa de Python ≥ 3.10, uv, CMake ≥ 3.20 e um compilador C++17 (no Windows, o Visual Studio com as ferramentas de C++; os wheels publicados usam o clang-cl).

uv sync                                    # compila o C++ e instala o pacote no ambiente
uv run python tools/check.py               # formata, lint, tipos e testes, parando no primeiro que falhar
uv run python tools/check.py --then bench_hash   # ... e, se tudo passar, um benchmark
uv run python tools/gen_bindings.py        # depois de mudar a assinatura de uma função C++

Ferramentas (tools/):

comando o que faz
uv run python tools/make_data.py --rows 1000000 --cols 50 gera um par de tabelas com o resultado esperado (data/bench/)
uv run python tools/make_golden.py regrava os gabaritos dos casos de borda (tests/golden/) com o datacompolars 0.4.4
uv run python tools/bench_baseline.py mede a linha de base (datacompolars 0.4.4) e escreve docs/benchmarks/baseline.md
uv run python tools/bench_hash.py mede o nini-datacomp nos mesmos casos (--mode columnwise para o caminho com tolerância) e escreve docs/benchmarks/fase2.md / fase3.md
uv run python tools/diag_profile.py --case 1000000x50 onde vai o tempo de uma comparação (cProfile e o planejamento por partes)

No Windows, para compilar como os wheels: $env:DC_CLANGCL = "1" antes do uv sync (precisa dos componentes "C++ Clang Compiler for Windows" e "MSBuild support for LLVM (clang-cl) toolset" no Visual Studio Installer).

variável efeito
NINI_DATACOMP_LIB caminho de uma biblioteca compilada à mão (ex. com sanitizers)
NINI_DATACOMP_THREADS número de threads (padrão: todas as CPUs disponíveis)
NINI_DATACOMP_POOL=0 desliga o pool de memória do C++ (só para comparar)

Licença

Apache-2.0 (veja LICENSE e NOTICE).

Metadata

Release files for nini-datacomp 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nini-datacomp 0.3.0
File Size Uploaded Provenance Actions
nini_datacomp-0.3.0.tar.gz 475.4 kB With provenance Details for nini_datacomp-0.3.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for nini-datacomp 0.3.0
File Actions
nini_datacomp-0.3.0-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details for nini_datacomp-0.3.0-py3-none-win_arm64.whl
nini_datacomp-0.3.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for nini_datacomp-0.3.0-py3-none-win_amd64.whl
nini_datacomp-0.3.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for nini_datacomp-0.3.0-py3-none-musllinux_1_2_x86_64.whl
nini_datacomp-0.3.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for nini_datacomp-0.3.0-py3-none-musllinux_1_2_aarch64.whl
nini_datacomp-0.3.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details for nini_datacomp-0.3.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
nini_datacomp-0.3.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.24+ ARM64, Linux glibc 2.28+ ARM64 Details for nini_datacomp-0.3.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
nini_datacomp-0.3.0-py3-none-macosx_11_0_x86_64.whl Python 3 none macOS 11.0+ x86-64 Details for nini_datacomp-0.3.0-py3-none-macosx_11_0_x86_64.whl
nini_datacomp-0.3.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for nini_datacomp-0.3.0-py3-none-macosx_11_0_arm64.whl

Total release size: 4.8 MB

Release files / nini_datacomp-0.3.0.tar.gz

Download URL nini_datacomp-0.3.0.tar.gz
Size 475.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5362bf2dac0b1e97c479ab028e1bfc1acf20df85830aa6e1452179a5401b7e69
BLAKE2b-256 checksum
How to use checksums
da5ac85d7001922ff4808832e0cb188cd132752e02aaaba5e99c30c9afffd4e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-win_arm64.whl

Download URL nini_datacomp-0.3.0-py3-none-win_arm64.whl
Size 348.0 kB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
3621d132727be9973db250871c2e8dece65bb7dd8fb4953bb46826eca7d6c706
BLAKE2b-256 checksum
How to use checksums
a11b8b888ddd4b2340649b320089f80fe400ed69ce457ba6bbacab9c9f6570c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-win_amd64.whl

Download URL nini_datacomp-0.3.0-py3-none-win_amd64.whl
Size 384.7 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
760a8bec4a3557b27894555db3498895d202e4ee78aa2fc5155b21227be5996d
BLAKE2b-256 checksum
How to use checksums
7f5e0bcd947a03c2a2b61a683af48e2d142e4bd2f05dfd8bde0124dacae55b54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-musllinux_1_2_x86_64.whl

Download URL nini_datacomp-0.3.0-py3-none-musllinux_1_2_x86_64.whl
Size 1.3 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
d1e8f23ffc56a1a7ec2418223ef4f052cf95d3c3d4074898c8128dcf0f751fca
BLAKE2b-256 checksum
How to use checksums
353e2d3e54b3da72c8947326b2edde0448b17e3458f63c699ce4bb99a37b1918
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-musllinux_1_2_aarch64.whl

Download URL nini_datacomp-0.3.0-py3-none-musllinux_1_2_aarch64.whl
Size 1.3 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
bcef5a07b0fabc288ff77d65a75764f2657c42b51d7a448d1f337a4e5a957fe4
BLAKE2b-256 checksum
How to use checksums
2c1afca2753f1d79e0c18620a629860143bdf848825d25f77027330fc35e5519
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL nini_datacomp-0.3.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 284.8 kB
Tags Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
35d40846ac32ac28712d3ddf4a5babf619247e7d8ac3e28dc3f8afb4de7bbfe9
BLAKE2b-256 checksum
How to use checksums
9b070da96ef3ae9a0f0f0b7ba65d1e792347503215631311a90eceec96055c18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL nini_datacomp-0.3.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 271.3 kB
Tags Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
8b5e40b82a7c4db22cb8c5c16eed3da95806eb82f0c2ac583823ab45c51ede67
BLAKE2b-256 checksum
How to use checksums
45967b66bceeaaa5f3c2c450916c6c678f9baf4c944ee614de63ec151d7bd20c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-macosx_11_0_x86_64.whl

Download URL nini_datacomp-0.3.0-py3-none-macosx_11_0_x86_64.whl
Size 260.4 kB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
579b714c1d966c6928b10095624f82aa0c48e7a1aff03e309dbe9cfc6f330aad
BLAKE2b-256 checksum
How to use checksums
f0fad358bec31593edd21b050ad2f1fdf41e272f622b20aa8ec02fd9d279413c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / nini_datacomp-0.3.0-py3-none-macosx_11_0_arm64.whl

Download URL nini_datacomp-0.3.0-py3-none-macosx_11_0_arm64.whl
Size 246.9 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f47d3b85a2b58d60c02e0d707a47cc30e58fa28b2b3480b4e4542c9e16468560
BLAKE2b-256 checksum
How to use checksums
140372cb7b2a141a1dcb63ce448edf912bf26cdeea8893dfdb9cd4574f45677d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Security for nini-datacomp 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 9 files in this release have been uploaded with provenance metadata.

Select from 9 files

Attestation for nini_datacomp-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page