tomllib parse_float: decimais precisos no TOML

Publicado em: 18/10/2026
Tempo de leitura: 5 minutos
Código Python para leitura precisa de configurações TOML

O parâmetro parse_float do módulo tomllib permite controlar como números de ponto flutuante encontrados em arquivos TOML são convertidos no Python. Por padrão, valores como 0.1, 3.14 ou 1e-6 viram objetos float. Isso é suficiente para muitas configurações, mas pode causar limitações quando o projeto exige precisão decimal, rastreabilidade financeira, validação adicional ou tipos numéricos personalizados.

Neste guia, você aprenderá como usar tomllib.load e tomllib.loads com parse_float, quando escolher Decimal, quais erros evitar e como integrar essa técnica a aplicações reais. Para uma introdução ao formato, veja também nosso artigo sobre tomllib no Python.

O que é parse_float

parse_float recebe uma função que será chamada para cada literal de ponto flutuante encontrado pelo parser TOML. Essa função recebe o texto original do número e deve devolver o objeto que representará aquele valor no dicionário final.

import tomllib
from decimal import Decimal

config = tomllib.loads('taxa = 0.1', parse_float=Decimal)
print(config['taxa'])
print(type(config['taxa']))

O resultado é um Decimal('0.1'), preservando exatamente os dígitos escritos no arquivo. Isso evita a representação binária aproximada típica de float.

Por que float pode não ser suficiente

O tipo float segue o padrão IEEE 754 e representa números em base binária. Muitos decimais simples não possuem representação binária exata. Assim, somas aparentemente triviais podem produzir resultados como 0.30000000000000004. Em cálculos científicos isso costuma ser aceitável, mas em preços, impostos, taxas e limites regulatórios pode ser inadequado.

O uso de Decimal é especialmente útil quando o arquivo TOML contém valores monetários, percentuais, fatores de conversão ou parâmetros que precisam ser comparados exatamente. Você pode aprofundar esse tema no artigo sobre Decimal no Python.

Usando com tomllib.load

Ao ler um arquivo binário, passe a função diretamente para tomllib.load:

from decimal import Decimal
import tomllib

with open('config.toml', 'rb') as arquivo:
    dados = tomllib.load(arquivo, parse_float=Decimal)

É importante abrir o arquivo em modo binário, pois essa é a interface esperada por tomllib.load. O restante dos tipos TOML continua sendo convertido normalmente: inteiros viram int, booleanos viram bool, datas viram tipos de datetime e strings permanecem strings.

Criando um conversor personalizado

A função fornecida não precisa ser diretamente Decimal. Você pode criar uma função para validar limites, registrar valores ou aplicar contexto decimal.

from decimal import Decimal

def parse_decimal_limitado(texto: str) -> Decimal:
    valor = Decimal(texto)
    if valor < 0:
        raise ValueError('valor negativo não permitido')
    return valor

Esse padrão é útil para rejeitar configurações inválidas logo durante a leitura. Ainda assim, não concentre toda a validação no parser. Após carregar os dados, valide estrutura, campos obrigatórios, relações entre valores e regras de negócio. Veja nosso guia sobre dataclasses no Python para organizar configurações tipadas.

Restrições importantes

A função de parse_float deve devolver um valor que não seja lista nem dicionário. Essa restrição evita ambiguidades na estrutura interna produzida pelo parser. Também é recomendável que a função seja determinística, rápida e livre de efeitos colaterais inesperados.

Se o conversor lançar uma exceção, a leitura será interrompida. Portanto, capture erros na camada responsável pelo carregamento da configuração e apresente mensagens claras ao usuário.

try:
    dados = tomllib.loads(texto, parse_float=parse_decimal_limitado)
except (tomllib.TOMLDecodeError, ValueError) as erro:
    print(f'Configuração inválida: {erro}')

Precisão e contexto Decimal

O construtor Decimal preserva o literal recebido, mas operações futuras obedecem ao contexto decimal ativo. Você pode configurar precisão, arredondamento e armadilhas com decimal.getcontext ou localcontext. Isso importa principalmente quando os valores lidos serão multiplicados, divididos ou agregados.

Evite converter primeiro para float e depois para Decimal, pois a aproximação já terá ocorrido. A grande vantagem de parse_float=Decimal é receber diretamente o texto original do arquivo.

Exemplo com preços

# config.toml
[produto]
preco = 19.90
desconto = 0.15
from decimal import Decimal
import tomllib

with open('config.toml', 'rb') as arquivo:
    config = tomllib.load(arquivo, parse_float=Decimal)

preco = config['produto']['preco']
desconto = config['produto']['desconto']
final = preco * (Decimal('1') - desconto)
print(final.quantize(Decimal('0.01')))

O cálculo mantém a semântica decimal desde a leitura até o arredondamento final.

Tipos personalizados

Você também pode devolver um wrapper próprio, desde que ele seja compatível com o restante do código. Um wrapper pode guardar o literal original, unidade, origem da configuração ou metadados de auditoria. Contudo, esse design aumenta a complexidade e deve ser reservado para sistemas que realmente precisam dessa informação.

Em aplicações comuns, Decimal oferece o melhor equilíbrio entre clareza, precisão e suporte da biblioteca padrão.

Validação depois do parsing

O TOML garante sintaxe, não regras de negócio. Depois de carregar, confirme tipos, intervalos e campos obrigatórios. Bibliotecas de validação ou classes próprias podem transformar o dicionário bruto em uma configuração segura. Para padrões de tipagem, consulte type hints no Python.

Testes recomendados

Crie testes com decimais simples, notação científica, valores negativos, zeros, limites muito grandes e entradas inválidas. Verifique tanto o valor quanto o tipo retornado. Teste também mensagens de erro e comportamento do aplicativo quando a configuração não pode ser carregada.

def test_decimal_exato():
    dados = tomllib.loads('valor = 0.1', parse_float=Decimal)
    assert dados['valor'] == Decimal('0.1')
    assert isinstance(dados['valor'], Decimal)

Nos testes, lembre-se de que inteiros TOML não passam por parse_float. O literal 1 continua sendo int, enquanto 1.0 passa pelo conversor.

Desempenho

Decimal é mais lento que float, mas arquivos de configuração geralmente são pequenos e lidos poucas vezes. Na maioria dos sistemas, a diferença é irrelevante. Para grandes volumes de dados, faça medições reais antes de decidir. Não use TOML como formato de processamento massivo quando a necessidade principal é desempenho analítico.

Segurança e manutenção

Use conversores simples e auditáveis. Evite executar código dinâmico, acessar rede ou alterar estado global durante o parsing. Defina claramente quais campos aceitam decimais e documente que o resultado não será float. Isso reduz surpresas para outras partes do sistema.

A documentação oficial de tomllib descreve a assinatura e as regras do parser, enquanto a especificação em TOML detalha a sintaxe dos números.

Quando usar parse_float

Use parse_float quando precisão decimal for uma exigência, quando você precisar validar literais durante a leitura ou quando tipos personalizados trouxerem valor concreto. Continue com o padrão float para configurações simples de interface, limites aproximados, coordenadas, métricas ou parâmetros que toleram representação binária.

Conclusão

tomllib oferece uma forma segura e direta de ler TOML, e parse_float amplia esse controle sem exigir um parser externo. Com Decimal, você preserva os valores escritos, evita aproximações prematuras e constrói configurações mais confiáveis. Combine essa capacidade com validação posterior, testes e tratamento explícito de erros para obter um fluxo robusto e fácil de manter.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Validação de endereços de e-mail com getaddresses strict no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    getaddresses strict: valide listas de e-mail

    Aprenda getaddresses strict no Python para analisar listas de e-mail com validação mais rigorosa, segurança e testes.

    Ler mais

    Tempo de leitura: 5 minutos
    17/10/2026
    Código Python representando functools.Placeholder e argumentos posicionais
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    functools.Placeholder: argumentos flexíveis no partial

    Aprenda functools.Placeholder no Python 3.14 para preencher argumentos posicionais flexíveis com partial e partialmethod.

    Ler mais

    Tempo de leitura: 5 minutos
    17/10/2026
    Código em tela representando t-strings no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    T-strings no Python 3.14: templates estruturados

    Aprenda t-strings no Python 3.14, entenda Template e Interpolation e crie renderizadores estruturados, extensíveis e mais seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    16/10/2026
    CPU e módulos de memória representando shared_memory track no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    shared_memory track: controle o resource tracker

    Aprenda o parâmetro track de multiprocessing.shared_memory no Python para controlar o resource tracker e evitar remoções prematuras.

    Ler mais

    Tempo de leitura: 6 minutos
    16/10/2026
    Unidade de armazenamento de dados representando compactação com compression.zstd no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: streams e compressão segura

    Aprenda compression.zstd no Python para compactar arquivos e dados com velocidade, streaming, dicionários e segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    15/10/2026
    Código em tela para diagnóstico de processos com sys.remote_exec no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sys.remote_exec: diagnostique processos Python

    Aprenda sys.remote_exec no Python para diagnosticar processos em execução com scripts controlados, segurança e boas práticas.

    Ler mais

    Tempo de leitura: 6 minutos
    15/10/2026