On the 16.0 branch, account_invoice_en16931/models/account_move_line.py (lines 160 and 228) uses:
isinstance(vat_dict.get("vat_rate"), int | float)
int | float here is evaluated at runtime as the second argument of isinstance(), not just used as a type annotation. This PEP 604 union syntax between two type objects only works from Python 3.10 onwards — on Python 3.9 (still common on Odoo 16 deployments, e.g. Debian 11), it raises:
TypeError: unsupported operand type(s) for |: 'type' and 'type'
Traceback happens when generating the EN16931 XML (e.g. via generate_en16931_xml() / the Saxon test button), on any invoice line.
Suggested fix (behaviourally identical, works on all Python versions):
isinstance(vat_dict.get("vat_rate"), (int, float))
On the 16.0 branch,
account_invoice_en16931/models/account_move_line.py(lines 160 and 228) uses:int | floathere is evaluated at runtime as the second argument ofisinstance(), not just used as a type annotation. This PEP 604 union syntax between twotypeobjects only works from Python 3.10 onwards — on Python 3.9 (still common on Odoo 16 deployments, e.g. Debian 11), it raises:Traceback happens when generating the EN16931 XML (e.g. via
generate_en16931_xml()/ the Saxon test button), on any invoice line.Suggested fix (behaviourally identical, works on all Python versions):