details: https://code.tryton.org/tryton/commit/1c859b480ffb
branch: default
user: Cédric Krier <[email protected]>
date: Wed Jul 29 18:28:56 2026 +0200
description:
Warn about using too much significant digits for float and numeric
Closes #14870
diffstat:
modules/account_invoice/payment_term.py | 4 ++--
modules/account_invoice/tests/test_module.py | 2 +-
modules/currency/currency.py | 4 ++--
modules/product/uom.py | 2 +-
modules/timesheet_cost/company.py | 2 +-
trytond/trytond/model/fields/float.py | 8 ++++++++
6 files changed, 15 insertions(+), 7 deletions(-)
diffs (102 lines):
diff -r 4cb9e4c709d5 -r 1c859b480ffb modules/account_invoice/payment_term.py
--- a/modules/account_invoice/payment_term.py Thu Aug 20 16:33:20 2026 +0200
+++ b/modules/account_invoice/payment_term.py Wed Jul 29 18:28:56 2026 +0200
@@ -90,7 +90,7 @@
('percent_on_total', 'Percentage on Total'),
('remainder', 'Remainder'),
], 'Type', required=True)
- ratio = fields.Numeric('Ratio', digits=(14, 10),
+ ratio = fields.Numeric('Ratio', digits=(8, 8),
domain=[
If(Eval('type').in_(['percent', 'percent_on_total'])
& ~Eval('divisor', 0),
@@ -101,7 +101,7 @@
'invisible': ~Eval('type').in_(['percent', 'percent_on_total']),
'required': Eval('type').in_(['percent', 'percent_on_total']),
})
- divisor = fields.Numeric('Divisor', digits=(10, 14),
+ divisor = fields.Numeric('Divisor', digits=(8, 8),
states={
'invisible': ~Eval('type').in_(['percent', 'percent_on_total']),
'required': Eval('type').in_(['percent', 'percent_on_total']),
diff -r 4cb9e4c709d5 -r 1c859b480ffb
modules/account_invoice/tests/test_module.py
--- a/modules/account_invoice/tests/test_module.py Thu Aug 20 16:33:20
2026 +0200
+++ b/modules/account_invoice/tests/test_module.py Wed Jul 29 18:28:56
2026 +0200
@@ -116,7 +116,7 @@
('create', [{
'type': 'percent',
'divisor': Decimal(3),
- 'ratio': Decimal('0.3333333333'),
+ 'ratio': Decimal('0.33333333'),
}, {
'type': 'remainder',
}]),
diff -r 4cb9e4c709d5 -r 1c859b480ffb modules/currency/currency.py
--- a/modules/currency/currency.py Thu Aug 20 16:33:20 2026 +0200
+++ b/modules/currency/currency.py Wed Jul 29 18:28:56 2026 +0200
@@ -49,7 +49,7 @@
numeric_code = fields.Char('Numeric Code', size=3,
help="The 3 digits ISO currency code.")
rate = fields.Function(fields.Numeric(
- "Current rate", digits=(rate_decimal * 2, rate_decimal)),
+ "Current rate", digits=(rate_decimal * 2 - 1, rate_decimal)),
'get_rate')
rates = fields.One2Many('currency.currency.rate', 'currency', 'Rates',
help="Add floating exchange rates for the currency.")
@@ -248,7 +248,7 @@
"Date", required=True,
help="From when the rate applies.")
rate = fields.Numeric(
- "Rate", digits=(rate_decimal * 2, rate_decimal), required=True,
+ "Rate", digits=(rate_decimal * 2 - 1, rate_decimal), required=True,
domain=[
('rate', '>', 0),
],
diff -r 4cb9e4c709d5 -r 1c859b480ffb modules/product/uom.py
--- a/modules/product/uom.py Thu Aug 20 16:33:20 2026 +0200
+++ b/modules/product/uom.py Wed Jul 29 18:28:56 2026 +0200
@@ -16,7 +16,7 @@
__all__ = ['uom_conversion_digits']
uom_conversion_digits = (
- config.getint('product', 'uom_conversion_decimal', default=12),) * 2
+ None, config.getint('product', 'uom_conversion_decimal', default=12))
class UomCategory(ModelSQL, ModelView):
diff -r 4cb9e4c709d5 -r 1c859b480ffb modules/timesheet_cost/company.py
--- a/modules/timesheet_cost/company.py Thu Aug 20 16:33:20 2026 +0200
+++ b/modules/timesheet_cost/company.py Wed Jul 29 18:28:56 2026 +0200
@@ -10,7 +10,7 @@
__all__ = ['price_digits']
-price_digits = (16, config.getint(
+price_digits = (None, config.getint(
'timesheet_cost', 'price_decimal', default=4))
diff -r 4cb9e4c709d5 -r 1c859b480ffb trytond/trytond/model/fields/float.py
--- a/trytond/trytond/model/fields/float.py Thu Aug 20 16:33:20 2026 +0200
+++ b/trytond/trytond/model/fields/float.py Wed Jul 29 18:28:56 2026 +0200
@@ -1,5 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+
+import warnings
+
from trytond.pyson import PYSON, PYSONEncoder
from trytond.tools import cached_property
@@ -17,6 +20,11 @@
if isinstance(i, PYSON):
assert i.types() <= {int, type(None)}, \
"PYSON digits must return an integer or None"
+ if (digits := sum(v for v in value if isinstance(v, int))) > 17:
+ warnings.warn(
+ f"{digits} significant digits is greater than 17, "
+ "there may be lost of fidelity",
+ stacklevel=4)
def _get_digits_depends(field):