Is there a way to customize error messages shown by PyInputPlus?

Viewed 241

I've recently learned about PyInputPlus and how to use it. It is really awesome, but I am wondering is there a way to customize error messages that PyInputPlus shows when user enters invalid values. For example, in the code below

import pyinputplus as pyip
response=pyip.inputInt('please, enter a number: ')

if a user enters letter 's', PyInputPlus shows -

's' is not an integer

I would like to cutomize that message, to show it in a different (non-english) language. I tried to find the solution in the official documentation at PyInputPlus but found nothing except using inputCustom which I am not interested in.

3 Answers

If you are set on doing this with PyInputPlus, you can get the desired behavior using the parameter blockRegexes, which permits setting a custom error message (in the documentation, this is apparently wrongly documented for the non-existing parameter blocklistRegexes in PyInputPlus parameters):

blocklistRegexes (Sequence, None): A sequence of regex str or (regex_str, error_msg_str) tuples that, if matched, will explicitly fail validation.

Since it is simpler to write a regex that matches only integers than one that matches everything except them, I first used blockRegexes to forbid everything using the regex .* and then allowRegexes to add exceptions for integers using the regex ^-?\d+$' (only positive and negative integers, see https://regex101.com/r/1ymJzE/1).

The following example accepts negative or positive integers and prints a custom Spanish error message otherwise:

import pyinputplus as pyip

response = pyip.inputInt('please, enter a number: ',
             allowRegexes=[r'^-?\d+$'],
             blockRegexes=[(r'.*','¡Esto no es un número entero!')]
           )

Execution:

please, enter a number: a
¡Esto no es un número entero!
please, enter a number: 1-2
¡Esto no es un número entero!
please, enter a number: 3.2
¡Esto no es un número entero!
please, enter a number: 5,4
¡Esto no es un número entero!
please, enter a number: -12

You could also achieve the same with only blockRegexes by providing a regex that accepts everything but integers. This regex is a bit more complex if negative numbers should be allowed. See this answer to a respective question for a detailed explanation of the regex.

This code achieves the same result as the one above:

import pyinputplus as pyip

response = pyip.inputInt('please, enter a number: ',
             blockRegexes=[(r'[^-0-9]+|[0-9]+(?=-)|^-$|-{2,}','¡Esto no es un número entero!')]
           )

I think you can try to handle it as an exception. Put the logic in a 'try' block and what you want to show as error in the exception block.

try:
    #code logic
except SyntaxError: #for example
    print("You encountered a syntax error. ")

You can write the name of the error you're getting where I've written "SyntaxError".

To start, I would highly discourage using 3rd-party libraries whenever possible, because they will add faults you do not understand to your code. Many are extraordinarily useful, are well-supported, and/or have some feature it would take you an age to reproduce.

However, you can use int(input()) for this case, so do so!
(it will behave much more the way you expect)

Digging in the code, the validation actually calls another 3rd-party library by the same author

This looks like it goes to the code path here where the real Exception is and then goes here to be caught

Perhaps

while True:
    value = input("Please enter a number (q to quit): ")
    if value.startswith(('Q', 'q')):
        sys.exit("quit")
    try:
        value = int(value)
    except ValueError as ex:  # custom error message below!
        print("invalid input '{}', expected int".format(value))
    else:  # did not raise Exception
        break  # escape while loop

If you're ever looking for what a specific Exception is, repr() is very useful

>>> try:
...     raise ValueError("some string")
... except IOError:
...     print("reached IOError")
... except Exception as ex:
...     print("unexpected Exception: {}".format(repr(ex)))
...     raise ex
...
unexpected Exception: ValueError('some string')
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
  File "<stdin>", line 2, in <module>
ValueError: some string
Related