FlorianRhiem / pyGLFW

Python bindings for GLFW
MIT License
233 stars 36 forks source link

Improved error traceback for Python 2 #26

Closed RasmusN closed 5 years ago

RasmusN commented 5 years ago

The current traceback isn't so helpful when using Python 2. The traceback message typically looks something like this

Traceback (most recent call last):
  File "..\main.py", line 237, in process_user_input
    glfw.poll_events() # Get events from GLFW
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 1340, in poll_events
    _glfw.glfwPollEvents()
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 518, in errcheck
    _reraise(exc[1], exc[2])
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 51, in _reraise
    raise (exception, None, traceback)
TypeError: object.__init__() takes no parameters`

This issue arises since glfw re-raises the exception. Python 3 solves this by using raise exception.with_traceback(traceback). Solutions for this issue are discussed here https://stackoverflow.com/questions/18188563/how-to-re-raise-an-exception-in-nested-try-except-blocks

I tried Laurent LAPORTE's solution using the six-module and it seems to be working properly. However, I'm sure you want to avoid depending on this module.

# glfw/__init__.py
...
# Python 3 compatibility:
try:
    _getcwd = os.getcwdu
except AttributeError:
    _getcwd = os.getcwd
if sys.version_info.major > 2:
    _to_char_p = lambda s: s.encode('utf-8')
    def _reraise(exception, traceback):
        raise exception.with_traceback(traceback)
else:
    import six
    _to_char_p = lambda s: s
    def _reraise(exception, traceback):
        six.reraise(exception, None, traceback) 
        #raise (exception, None, traceback) # <- Old code
...

Perhaps there is some other way of solving this without using a 3rd part module?

FlorianRhiem commented 5 years ago

Thank you for pointing this out. Would the issue be solved by using the following code for Python 2?

def _reraise(exception, traceback):
    # wrapped in exec, as python 3 does not support this variant of raise
    exec("raise exception, None, traceback")
RasmusN commented 5 years ago

Yes! That solution seems to work.

FlorianRhiem commented 5 years ago

Thanks, fixed in 87767dfbe15ba15d2a8338cdfddf6afc6a25dff5.