I figured out the answer is that the __getattr__ is called only if the attribute search starts at the instance object. But if the attribute search explicitly on the class and instance is skipped __getattr__ is never called.
class B():
data = 'abcd'
def __getattr__(self, name):
print('You are looking for something that doesn\'t exist')
return None
b = B()
b.a
You are looking for something that doesn't exist
B.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: class B has no attribute 'a'
Hence in classic classes the search for __getitem__ starts at instance object and __getattr__ is invoked whereas in the new style class the search starts at class object and hence __getattr__ is not invoked.