Python isnumeric() and isdigit() on Unexpected Characters
Some unexpected characters are numeric or digits. I found a trait of str.isnumeric() and str.isdigit() that I didn’t expect.
What the help texts say
Let’s first look at the help texts (Python 3.10.6). isdigit(self, /):
Return True if the string is a digit string, False otherwise.
A string is a digit string if all characters in the string are digits and there
is at least one character in the string.
And conversely, isnumeric(self, /):
Return True if the string is a numeric string, False otherwise.
A string is numeric if all characters in the string are numeric and there
is at least one character in the string.
This gives the impression that a string consisting only of digits must be a number, and in most cases this works as expected:
>>> num_str = "1234"
>>> num_str.isdigit()
True
>>> num_str.isnumeric()
True
>>> int(num_str)
1234
Superscripts and fractions
But then there are superscript numbers and fraction characters, which I didn’t expect and which you should consider:
>>> pow3 = '³'
>>> pow3.isdigit()
True
>>> pow3.isnumeric()
True
>>> int(pow3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '³'
>>> quarter = '¼'
>>> quarter.isdigit()
False
>>> quarter.isnumeric()
True
>>> float(quarter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '¼'
Validate with a regular expression
So consider using good old (and slower) regular expressions to validate input that is then fed to int() or float():
import re
re.match('\d+', pow3) # this pretend-digit is no match for regex :D