Which exception should I raise on bad/illegal argument combinations in Python?

前端 未结 7 1338
北荒
北荒 2020-12-02 04:09

I was wondering about the best practices for indicating invalid argument combinations in Python. I\'ve come across a few situations where you have a function like so:

<
相关标签:
7条回答
  • 2020-12-02 04:33

    I'm not sure I agree with inheritance from ValueError -- my interpretation of the documentation is that ValueError is only supposed to be raised by builtins... inheriting from it or raising it yourself seems incorrect.

    Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.

    -- ValueError documentation

    0 讨论(0)
  • 2020-12-02 04:40

    I've mostly just seen the builtin ValueError used in this situation.

    0 讨论(0)
  • 2020-12-02 04:42

    It depends on what the problem with the arguments is.

    If the argument has the wrong type, raise a TypeError. For example, when you get a string instead of one of those Booleans.

    if not isinstance(save, bool):
        raise TypeError(f"Argument save must be of type bool, not {type(save)}")
    

    Note, however, that in Python we rarely make any checks like this. If the argument really is invalid, some deeper function will probably do the complaining for us. And if we only check the boolean value, perhaps some code user will later just feed it a string knowing that non-empty strings are always True. It might save him a cast.

    If the arguments have invalid values, raise ValueError. This seems more appropriate in your case:

    if recurse and not save:
        raise ValueError("If recurse is True, save should be True too")
    

    Or in this specific case, have a True value of recurse imply a True value of save. Since I would consider this a recovery from an error, you might also want to complain in the log.

    if recurse and not save:
        logging.warning("Bad arguments in import_to_orm() - if recurse is True, so should save be")
        save = True
    
    0 讨论(0)
  • 2020-12-02 04:43

    I think the best way to handle this is the way python itself handles it. Python raises a TypeError. For example:

    $ python -c 'print(sum())'
    Traceback (most recent call last):
    File "<string>", line 1, in <module>
    TypeError: sum expected at least 1 arguments, got 0
    

    Our junior dev just found this page in a google search for "python exception wrong arguments" and I'm surprised that the obvious (to me) answer wasn't ever suggested in the decade since this question was asked.

    0 讨论(0)
  • 2020-12-02 04:44

    I would just raise ValueError, unless you need a more specific exception..

    def import_to_orm(name, save=False, recurse=False):
        if recurse and not save:
            raise ValueError("save must be True if recurse is True")
    

    There's really no point in doing class BadValueError(ValueError):pass - your custom class is identical in use to ValueError, so why not use that?

    0 讨论(0)
  • 2020-12-02 04:54

    I would inherit from ValueError

    class IllegalArgumentError(ValueError):
        pass
    

    It is sometimes better to create your own exceptions, but inherit from a built-in one, which is as close to what you want as possible.

    If you need to catch that specific error, it is helpful to have a name.

    0 讨论(0)
提交回复
热议问题