Поведение IPython отличается для файлов.py и.ipy, несмотря на то, что скрипт является "чистым" питоном (перехватывает обработчик пользовательских обработчиков исключений)

Я написал обработчик исключений, который предназначен для регистрации всех необработанных исключений в коде перед вызовом обычных обработчиков исключений python. У Python и iPython есть несколько разные способы сделать это. Я обнаружил, что способ iPython сделать это работает только при запуске из интерактивного сеанса или при использовании расширения имени файла ".ipy", несмотря на тот факт, что я не верю, что использую какую-либо "магию" и обычный способ Python сделать это не будет работать в ipython, даже если сценарий называется.py и "Чистый питон".

Я хочу, чтобы можно было установить собственный обработчик исключений для iPython из скрипта, даже если он вызывается из командной строки как файл ".py".

Пример кода testcase.py:

import sys

def my_exc(exc_type, exc_value, exc_traceback):
    """Regular Python exception handler with inputs mirroring sys.excepthook"""

    print('\nDoing Custom Stuff (Python exc handler)\n')
    # Call the old sys.excepthook as well
    sys.__excepthook__(exc_type, exc_value, exc_traceback)

def imy_exc(shell, exc_type, exc_value, exc_tb, tb_offset=None):
    """IPythonic exception handler, following instructions in 
    set_custom_exc here:
    http://ipython.org/ipython-doc/stable/api/generated/IPython.core.interactiveshell.html"""

    print('\nDoing Custom Stuff (iPython exc handler)\n')
    # Do regular IPython stuff as well
    shell.showtraceback((exc_type, exc_value, exc_tb), tb_offset=tb_offset)

try:
    __IPYTHON__
    from IPython import get_ipython
    shell = get_ipython()
    if shell:
        print('Shell Active')
        # Set my custom exception handler for the current IPython shell
        get_ipython().set_custom_exc((Exception,), imy_exc)
    else:
        print('In IPython, but no active shell')
        sys.excepthook = my_exc    
except NameError:
    print('NameError, falling back on regular Python way')
    # use the standard python excepthook override
    sys.excepthook = my_exc

def makeproblem():
    1/0

makeproblem()

Поведение:

Работает:

1. $ ipython testcase.ipy
- result: "shell active", "Doing Custom Stuff (iPython exc handler)""

2. $ ipython -c="execfile('testcase.py')
- result: "NameError, falling back on regular Python way", "Doing Custom Stuff (Python exc handler)" (This one is particularly puzzling)

3. $ python testcase.py
- result: "NameError, falling back on regular Python way", "Doing Custom Stuff (Python exc handler)"

4. $ ipython
In[0]: execfile('testcase.py')
or
In[0]: %paste #pasting testcase.py    
- result: "shell active", "Doing Custom Stuff (iPython exc handler)""

Не работает:

1. $ ipython testcase.py
- result: "Shell Active", no override statement

2. $ ipython -c="% run 'testcase.py'"
- result: "Shell Active", no override statement

Поведение% run vs execfile подсказывает мне, что это как-то связано со сценарием, запускаемым в автономном пространстве имен, но я не смог понять это. Это может быть красная сельдь, хотя. Другой совет, который я имею, заключается в том, что если я дам дамп фреймов, используя inspect в сценарии testcase выше, в рабочих случаях в верхней части будут следующие вызовы интерактивной оболочки, которые не отображаются иначе:

(<frame object at 0x10264b500>, '/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/IPython/core/interactiveshell.py', 2883, 'run_code', ['exec(code_obj, self.user_global_ns, self.user_ns)\n'], 0)
(<frame object at 0x10264a790>, '/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/IPython/core/interactiveshell.py', 2827, 'run_ast_nodes', ['if self.run_code(code):\n'], 0)
(<frame object at 0x10263eda0>, '/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/IPython/core/interactiveshell.py', 2741, 'run_cell', ['interactivity=interactivity, compiler=compiler)\n'], 0)
(<frame object at 0x10263e7c0>, '/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/IPython/core/interactiveshell.py', 2604, 'safe_execfile_ipy', ['self.run_cell(cell, silent=True, shell_futures=False)\n'], 0)

0 ответов

Другие вопросы по тегам