inspect_shell: Pythonプログラムにreplを組込む

https://github.com/amoffat/Inspect-Shell

試しにdjangoの開発サーバにシェルを組み込んでみよう。

views.py


# -*- coding: utf-8 -*-
from django.http import HttpResponse, HttpResponseRedirect

data=dict(msg='OH HAI',
inspect_shell_imported=False)

def inspect_shell(request):
""" inspect_shellをテストするページハンドラ
GETするとdata['msg']が出力される。
"""
# モジュールレベルでインポートするとワーカープロセスじゃなくてその親で
# inspect shellが走ってしまう。viewハンドラが呼ばれたときにインポートする
# ことによってHTTPのリクエストに答えるプロセスにシェルをロードする。
# djangoのマルチスレッドな開発サーバによる使用を想定している。
if not data['inspect_shell_imported']:
import inspect_shell
data['inspect_shell_imported']=True


return HttpResponse(data['msg'])

urls.py


urlpatterns = patterns('',
...
url(r'^inspect_shell/', 'main.views.inspect_shell'),
)

サーバ開始


$ python manage.py runserver
Validating models...

0 errors found
Django version 1.3.1, using settings 'dxh.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Inspec Shellで走っているdjangoをいじる

初期状態


$ w3m -dump http://localhost:8000/inspect_shell/
OH HAI

シェル接続


$ python inspect_shell.py

>> Inspect Shell v1.0
>> https://github.com/amoffat/Inspect-Shell

インポートできる!


localhost:1234> from main.views import data

データが見れる!


localhost:1234> data
{'inspect_shell_imported': True, 'msg': 'OH HAI'}

データに書き込み!


localhost:1234> data['msg']='Hoge'

メッセージが更新されている!


$ w3m -dump http://localhost:8000/inspect_shell/
Hoge

プロセスのpythonの状態をなんでも見ることができる


localhost:1234> import settings

localhost:1234> settings

localhost:1234> dir(settings)
['ADMINS', 'ADMIN_MEDIA_PREFIX', 'BACKEND_HOME', 'BACKEND_NAME', 'DATABASES', 'DEBUG', 'INSTALLED_APPS', 'LANGUAGE_CODE', 'LOGGING', 'LOG_DIR', 'MANAGERS', 'MEDIA_ROOT', 'MEDIA_URL', 'MIDDLEWARE_CLASSES', 'PROJECT_HOME', 'ROOT_URLCONF', 'RUNTIME_HOME', 'SECRET_KEY', 'SITE_ID', 'STATICFILES_DIRS', 'STATICFILES_FINDERS', 'STATIC_ROOT', 'STATIC_URL', 'TEMPLATE_DEBUG', 'TEMPLATE_DIRS', 'TEMPLATE_LOADERS', 'TIME_ZONE', 'USE_I18N', 'USE_L10N', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'os', 'sys']

使用上の注意

原作者が書いているけども、グローバルな変数を更新する際にこのシェルは何のロッキングもしない。あまり無茶するとプロセスが不整合な状態になりかねない。read-onlyな検査に使うのがベストな使い方だろう。
https://github.com/amoffat/Inspect-Shell "How to use"を参照

これでPythonが一歩LISPに近付いた。