swansonk14 / typed-argument-parser

Typed argument parser for Python
MIT License
505 stars 40 forks source link

Tap eats my custom error messages :( #135

Closed iago-lito closed 6 months ago

iago-lito commented 6 months ago

When providing my custom parsing function with the type argument, like in the following:

from tap import Tap

class Cli(Tap):
    value: int

    def configure(self):
        self.add_argument("value", type=Cli.custom_check)

    @staticmethod
    def custom_check(input: str):
        try:
            i = int(input)
        except:
            raise TypeError(f"Could not parse as an integer: {repr(input)}.")

        if i > 42:
            raise ValueError(f"Received {i}, but this program dislikes values above 42.")

        return i

cli = Cli()
args = cli.parse_args()
print(f"Received value: {args.value} (thank you).") 

I would expect my error message to show up in case of failure, but here is the output I get from tap instead:

$ python main.py 45
usage: main.py [-h] value
main.py: error: argument value: invalid custom_check value: '45'

How can I get my error message displayed instead?

iago-lito commented 6 months ago

Got it: I need to raise argparser.ArgumentTypeErrors instead.
This is unexpected since TypeError and ValueError are also supported by argparse.
Should I close or leave this issue open until the three types of errors are handled?

martinjm97 commented 6 months ago

Hi @iago-lito,

Thank you for raising this issue. Do you know if an implementation of this in pure argparse would produce the same error? In other words, does tap deviate from argparse in the way it handles errors?

--JK

iago-lito commented 6 months ago

No indeed @martinjm97. Good catch. The problem is upstream: https://github.com/python/cpython/issues/74406 :)

martinjm97 commented 5 months ago

Thank you for identifying this problem and finding the upstream issue!