0

I'm trying to use traceback.print_stack() to print the stack leading up to the error without including the line which actually prints the stack. e.g.:

import os
import pathlib
import sys
import traceback


def main():
  path = pathlib.Path('/foo')
  content_bytes = b''
  my_func(path, content_bytes)

def my_func(path, content_bytes):
  for (dirpath, dirnames, filenames) in os.walk(path, onerror=on_error(path)):
    for filename in filenames:
      file: bytes = open(dirpath + "/" + filename, "rb").read()
      content_bytes += file

def on_error(path):
  traceback.print_stack(sys._getframe(1))
  print("path is not a dir path supplied: {}".format(path))

main()

Assuming I have no dir named /foo this prints:

path is not a dir path supplied: /foo
  File "/{projectDir}/examples/test.py", line 22, in <module>
    main()
  File "/{projectDir}/examples/test.py", line 10, in main
    my_func(path, content_bytes)
  File "/{projectDir}/examples/test.py", line 13, in my_func
    for (dirpath, dirnames, filenames) in os.walk(path, onerror=on_error(path)):

As I want, but I'm bothered by the fact that I'm calling a protected sys method _getframe in order to do so. Pycharm also doesn't seem happy with me for doing this. Is there a more appropriate way to getting the current/previous frame in the stack that is used as the first arg of traceback.print_stack?

I see a lot of previous SO answers based on sys.exc_info() but this appears to be a tuple filled with None objects in this case.

topher217
  • 1,188
  • 12
  • 35
  • `sys._getframe` isn't a "protected sys method". It's a completely normal, documented function. There are other options without an underscore, but they're not actually any safer or more compatible or anything. – user2357112 Sep 27 '21 at 07:24
  • Pycharm is telling me, "Cannot find reference '_getframe' in 'sys.pyi'". Also the [python docs](https://docs.python.org/3/library/sys.html#sys._getframe) claims, "CPython implementation detail: This function should be used for internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python.". Should I not be heeding these warnings for some reason? I'd think there is some more exposed method of getting this via the traceback module no? – topher217 Sep 27 '21 at 07:43
  • Also the reason I claimed it to be a protected method is from the preceding underscore and its meaning according to [PEP8](https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables). – topher217 Sep 27 '21 at 07:46
  • The thing is, that warning applies to the *entire existence of stack frame objects*, not just this one particular function for retrieving them. If a Python implementation doesn't have `sys._getframe`, it probably doesn't have frame objects at all, so using a different function won't help. – user2357112 Sep 27 '21 at 12:36
  • Pycharm might not be happy about it, but you don't have to care. – AKX Sep 27 '21 at 12:39
  • Huh, I guess you're all right, as every other path I look to (e.g. `inspect` module, `traceback` etc.) all seem to use this `sys._getframe` call in the background. What would you then conclude about the python docs claiming it should be used for "internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python"? and the fact that it seems to be violating PEP8 if it is intended to be used outside the `sys` package? I'm less concerned about Pycharm warnings. Is a more stable exposed method in the works somewhere that I should keep on my radar for future use? – topher217 Sep 28 '21 at 02:09
  • Also I'm not a developer of commercial code, so completely ignorant on this subject, but curious if there are any security risks/restrictions inherent to using the `sys` module over say `inspect.stack` (which directly calls `sys._getframe(1)`. I.e. I'm grasping at straws to figure out WHY that underscore is there in the first place. Surely there must be some reason for it to have existed all the way up to python3.9. – topher217 Sep 28 '21 at 02:14

0 Answers0