Рубрики
Без рубрики

Как заставить скрипты Python отображать дружественные к Windows ошибки / Stacktrace

Автор оригинала: Arun Ravindran.

Большинство из нас любят распространять наши программы на Python среди других после того, как вы закончили писать аккуратный небольшой скрипт. Для пользователей Windows мы упаковываем его с помощью Py2exe или cx_freeze . Однако многие конечные пользователи не будут довольны появлением черного командного окна, например, при возникновении ошибки.

Конечно, альтернативой является создание полномасштабного приложения с графическим интерфейсом пользователя с использованием WXPython или PyFLTK . Даже последний, хотя и довольно легкий, добавляет несколько мегабайт к раздаче, когда все, что вам нужно, это простое окно сообщения, указывающее на ошибку или показывающее некоторый информационный текст. Ясно, что это перебор для ваших одноразовых скриптов Python.

Я обычно сталкиваюсь с этой проблемой, и я нашел хорошее решение. Ответ – библиотека ctypes , которая входит в стандартный дистрибутив Python 2.5 и новее. Он просто вызывает функцию окна сообщений из user32.dll (которая всегда присутствует в установке Windows). Когда основная проблема была решена, оставалось получить текст ошибки и трассировку стека.

Посмотрим, как выглядит код:

# Importing all the works for a native Win32 Message Box
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
prototype  WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags  (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
MessageBox  prototype(("MessageBoxA", windll.user32), paramflags)
 # For printing the stack
import sys
import traceback
from time import sleep

def show_popup(text):
    print text
    MessageBox(texttext, caption"Sample App Says...")

def mainloop():
    raise "Uff!"

if __name__  '__main__':
    try:
        mainloop()
    except:
        type, value, sys.last_traceback  sys.exc_info()
        lines  traceback.format_exception(type, value,sys.last_traceback)
        show_popup("Aiyooooo..... there has been an error!\n" +
            "Exception in user code:\n" +
            "".join(lines) +
            
            )
    finally:
        sleep(1) # show the console output for a second so that users can read it

РЕДАКТИРОВАТЬ: Вот как это выглядит в PyMail, одном из моих скриптов, выросших в приложение;)

Снимок экрана Python Stacktrace в окне сообщений