The whole routine can just be `return not self.free_symbols`. `is_number` is supposed to quickly tell if there is any free symbol. I don't think there is a fast way to do this with an expression that has limits unless the integrand and all limits are numbers. But instead of even starting this process (asking whether something is a number) and then continuing with the full analysis (to find what symbols *are there*) I guess you might as well just do the full traversal and find the symbols and analyze them as necessary.