Skip to content

Conversation

@heeplr
Copy link
Contributor

@heeplr heeplr commented Nov 5, 2025

This fixes two aspects:

  1. ensure that __str__() always returns a string (this closes DecimalElement.__str__() doesn't always return string type #94)
  2. provide a __float__() method so python string formatting doesn't fail with TypeError: must be real number, not DecimalElement

@heeplr heeplr changed the title ensure __str__() always returns a string fix string handling of DecimalElement Nov 5, 2025
@JulienPalard
Copy link
Contributor

JulienPalard commented Nov 21, 2025

Casting a Decimal to a float don't feel safe, precision can be lost.

I'd prefer forcing the type to be a Decimal in the __init__:

    self._value = None if value is None else Decimal(value)

and removing the __float__, that should work the same, without the precision loss.

Also you can just remove the __str__ as it's inheriting one from StringElement that is identical.

@heeplr heeplr force-pushed the fix-str-return branch 4 times, most recently from f3c9ff3 to ede5203 Compare November 24, 2025 09:37
@heeplr
Copy link
Contributor Author

heeplr commented Nov 24, 2025

@JulienPalard

you're absolutely right. I made the changes and it works as expected.

* remove __str__() to ensure string type by falling back to inherited StringElement.__str__()
* wrap __format__ method of _value
* enforce Decimal() type in __init__
@JulienPalard
Copy link
Contributor

In which part the __format__ is useful? Maybe in your Jinja template but not directly in drafthorse?

@heeplr
Copy link
Contributor Author

heeplr commented Nov 27, 2025

In which part the __format__ is useful? Maybe in your Jinja template but not directly in drafthorse?

Yes, in my case it's the jinja template that directly reads from the drafthorse document. It produces

TypeError: unsupported format string passed to DecimalElement.__format__

I think what's going on is, that DecimalElement has no __format__() and doesn't inherit one. Then python uses the __format__() of the str class which doesn't support "%f".

But it's not limitied to jinja:

foo = DecimalElement("foo", "foo", value=5.0)
print(foo)           # wrongly prints ""
print(foo._value)    # correctly prints "5"

With that __format__() the print(foo) works correctly (for anything that needs formatted output of DecimalElement like jinja).

I see no other way to solve that for any application besides accessing DecimalElement._value directly.

@JulienPalard
Copy link
Contributor

I see no other way to solve that for any application besides accessing DecimalElement._value directly.

OK your PR looks good to me.

But I'm not a contributor of the repo so I let the last word to those with the commit bit :)

@raphaelm raphaelm merged commit b3f9e39 into pretix:master Nov 27, 2025
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DecimalElement.__str__() doesn't always return string type

3 participants