jaraco / inflect

Correctly generate plurals, ordinals, indefinite articles; convert numbers to words
https://pypi.org/project/inflect
MIT License
957 stars 107 forks source link

ordinal: produces different results for decimal-as-string compared to decimal-as-float input #178

Closed jayaddison closed 1 year ago

jayaddison commented 1 year ago

Expected behaviour:

>>> from inflect import engine
>>> p = engine()
>>> p.ordinal(5.502)
'5.502nd'

Actual behaviour:

>>> from inflect import engine
>>> p = engine()
>>> p.ordinal(5.502)
'5th'

Possible cause:

Discovered by chance while adding test coverage related to ordinals for decimal numbers (if I'd represented the decimal by using a string, then I wouldn't have found this).

jayaddison commented 1 year ago

Possible cause:

That's not all:

pydantic's validation appears to read the num: Union[int, Word] argument from the method signature and uses it to coerce the resulting num variable to type int.

If that's the case, then the ordinal method likely does not handle many float inputs correctly.

A possible fix could involve adjusting the method's signature, and/or adjusting the type hints:

    @validate_arguments(config=dict(arbitrary_types_allowed=True))  # noqa: C901
    def ordinal(self, num: Union[Number, Word]) -> str:  # noqa: C901

Todo: confirm that this is true, and then provide relevant feedback on the pydantic issue tracker.

jaraco commented 1 year ago

On further consideration, I don't believe I truly understood the implications of #179, and while adopting Pydantic 2, I'm having to revisit this issue, because Pydantic is now (correctly) failing when an int or float is passed but the type annotation indicates Word.