It can be difficult to determine where warnings are coming from in user code when the stacklevel used points to pandas internals. There were recent improvements (~6 months ago) to find_stack_level. Doing some time tests, I get the following results on my machine:

  • Depth of 3: 0.149ms
  • Depth of 100: 1.48ms
Timing code
    # Added as a method of DataFrame
    def foo(self, depth, runs):
        if depth > 0:
            self.foo(depth-1, runs)
        else:
            import time
            from pandas.util._exceptions import find_stack_level

            timer = time.time()
            for _ in range(runs):
                find_stack_level()
            print(f'Average runtime: {(time.time() - timer) / runs : 0.10f}')

pd.DataFrame().foo(depth=100, runs=1000)

Is this reliable/performant enough to use universally in all warnings so that the stacklevel is always correct?

Comment From: jreback

yes this is find to do universally - we don't generally have warnings in performance sensitive code (though of course should be careful)

Comment From: rhshadrach

This is now used universally. Closing.