The a-b fails because automatic broadcasting occurs on the left, not the right.
np.zeros((2,7,5))-np.zeros((2,7))[:,:,None]
works
np.zeros((2,7,5))==np.zeros((2,7))[:,:,None]
and the equality test works element by element.
But as Kasra notes, in a==b, the element by element comparison will fail. Clearly the two arrays are not equal. Returning False is consistent with other Python uses of == (.__eq__ method). I don't know if the numpy developers even considered the alternative of returning a ValueError.
Consider what Python returns when comparing strings and lists:
'two'=='three'
[1,2,3]==[1]
'string'==['l','i','s','t']
I can't think of a case where __eq__ returns an error instead of False. But you might be able to code your own class that way.
Python documentation for __eq__ says:
A rich comparison method may return the singleton NotImplemented if it does not implement the operation for a given pair of arguments. By convention, False and True are returned for a successful comparison. However, these methods can return any value, so if the comparison operator is used in a Boolean context (e.g., in the condition of an if statement), Python will call bool() on the value to determine if the result is true or false.
numpy follows this - returning a boolean array if possible, False otherwise.
bool(np.zeros((2,7,5))==np.zeros((2,7))[:,:,None])
produces an error message:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
which is the root of a frequent SO question.