Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Annotate an Argument That Can Be Cast As Boolean?

I'm starting to get into type hints (aka annotations) in python 3.6, and I can't figure some of the dynamic aspects of this feature.

I wrote the following piece of code, and I want to add annotation and not sure how, even after looking through the docs on type hinting.

This is the function:

def validate_expression(expression: ?):
    try:
        assert expression
    except AssertionError as e:
        ...

expression needs to be anything that an assert works on (assuming any expression for which bool(expression) is valid).

What should I write instead of the question mark?

UPDATE:

I know that most python expressions can be cast as a Boolean, but the context in which I write this code is one where it is reasonable to expect an expression to not be a assertable.

The relevant example in my case is pandas.DataFrame. Running bool(pandas.DataFrame()) raises an error, and I have good reason to expect that someone might try to pass a dataframe to the validation function.

UPDATE 2: Following Chepner's comments and answer, I understand now that: 1. In the vast majority of cases, any python expression will have a valid casting to Boolean, and this is either covered by typing.Any or by not adding annotation at all. 2. In the edge case I was interested in, which is bool(pandas.DataFrame()) # --> ValueError, annotations won't help since this is a runtime error. 3. If there is another edge case that is relevant for static type hinting, I am not aware of it. 4. Given the rarity/non-existence of a relevant example, there's no out of the box type that generically describes just the quality of the ability to be casted to boolean (similar to typing.Iterable), and as far as I'm concerned it is not worth bending over backwards to address such an edge case (although it would be interesting to hear of relevant example and a bend-y solution!)

like image 691
yotammanor Avatar asked Aug 29 '19 14:08

yotammanor


People also ask

How do you annotate a return type in Python?

To annotate return value type, add -> immediately after closing the parameter parentheses, just before the function definition colon( : ): def announcement(language: str, version: float) -> str: ... The function now has type hints showing that it receives str and float arguments, and returns str .

How do I add type hints?

Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.

How do you annotate code in Python?

First, annotations can be fully implemented as decorators. You can just define an @annotate decorator and have it take an argument name and a Python expression as arguments and then store them in the target function's annotations attribute. This can be done for Python 2 as well.


1 Answers

Any value whatsoever can be used in a boolean context. An instance of object is considered to be a truthy value unless a descendent class provides an alternate definition; anything that is considered false (like an empty list, an empty str, an empty dict, False itself, etc) does so because it has been specially defined to be so.

As such, the only type hint you could use is typing.Any:

from typing import Any


def validate_expression(expression: Any):
    try:
        assert expression
    except AssertionError as e:
        ...

which, really, is barely worth stating explicitly.

like image 138
chepner Avatar answered Sep 24 '22 18:09

chepner