Mypy: isempty for collections

Created on 31 Mar 2017  路  3Comments  路  Source: python/mypy

_Note: This is rather a Python proposal, but opening it for comments here, as the suggestion comes from strictly typechecking the code._

When one wants to be strict with --strict-boolean the check for collection emptiness can be checked with one of the two ways:

things: Collection
if len(things) > 0:
    # do something

Or just silencing the type error with explicitly performing the boolean conversion:

things: Collection
if bool(things):
    # do something

The length checking is explicit, immediately understandable. The bool conversion is making pythonic construct if collection explicit, but it might not be immediately obvious what is the intent without understanding that the bool() is the same as the plain if expression which calls __bool__() which calls __len__() on collections.

It would make sense to introduce isempty(collection) that might have __is_empty__() as concrete implementation. Default implementation of __is_empty__() would do check on __len__() for collections as the __bool__() currently does.

Example:

things: Collection
if not isempty(things):
    # do something

EDIT: Added example.

Most helpful comment

This rather points out the foolishness of --strict-boolean.

All 3 comments

This rather points out the foolishness of --strict-boolean.

Summarizing the discussion on gitter: The reason I use --strict-boolean is that it prevents this type of bug:

def f(x: Optional[int] =None):
    if not x:
        # x is None, so we perform default action
        ...
    else:
        # x is not None
        ...

It may seem obvious that this code is wrong (x == 0 also ends up in the top branch), and yet I've seen this happen. The same can happen, of course, with def f(x: Iterable = None), where empty collection will be confused with None.

Since --strict-boolean prevents the conflation of x is None, x == 0, x == '' and len(x) == 0, it offers a trade-off between convenience and precision of intent. From my exeperience, most people would choose convenience in this case, and so won't use --strict-boolean, even if collections offered .empty() method (which only slightly reduces the verbosity of --strict-boolean).

There's just too much existing working code that depends on it. Forcing --strict-boolean on a codebase of any significant size is just not realistic.

Anyway the bar for isempty() is a million times higher (adding a builtin to Python? Go write a PEP and be prepared for a centi-thread on python-ideas and another on python-dev!) so I'm closing this until that's settled.

Was this page helpful?
0 / 5 - 0 ratings