A good answer is because you don't necessarily know if the thing you're getting is a list, a tuple, or a RepeatedCompositeFieldContainer (a protobuf list), or some other type that meets the Sequence/MutableSequence abstract base class contract. `if not foo` will check that they're all empty, while `if foo == []` will have unexpected behavior if foo starts returning a set tomorrow.
The generalization of this is to code against as generic an api as possible, you wouldn't do `list.__eq___(x, y)` in your code, but you're suggesting almost exactly that.
(granted you can still run into this kind of issue if foo is a generator, but that's a less common way to explode).
The style guide does tell you to use explicit `x is None`, instead of implicit bool when checking noneness, specifically to disambiguate between binary and ternary values, but usually that's not what you want.
The generalization of this is to code against as generic an api as possible, you wouldn't do `list.__eq___(x, y)` in your code, but you're suggesting almost exactly that.
(granted you can still run into this kind of issue if foo is a generator, but that's a less common way to explode).
The style guide does tell you to use explicit `x is None`, instead of implicit bool when checking noneness, specifically to disambiguate between binary and ternary values, but usually that's not what you want.