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.







