Last active
June 20, 2017 00:21
-
-
Save ryusas/5926b8e1c5b0d91d61e7187e864eeec9 to your computer and use it in GitHub Desktop.
Patch to make maya.app.general.executeDroppedPythonFile a bit safer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
u""" | |
maya.app.general.executeDroppedPythonFile を少しは安全にするパッチ。 | |
元の実装を尊重したラッパー `applyModestPatch` か | |
実装を丸ごと上書きする `applyOverridePatch` のどちらか好きな方を実行するとパッチが適用される。 | |
どちらとも繰り返し実行しても副作用はないので、切り替えも可能。 | |
元の実装の function は同モジュールの _executeDroppedPythonFile 属性に退避される。 | |
使用例:: | |
import safe_executeDroppedPythonFile | |
safe_executeDroppedPythonFile.applyOverridePatch() | |
""" | |
import sys | |
from os.path import splitext as _splitext | |
def applyModestPatch(): | |
u""" | |
ごく最低限なラッパーに置き換えるパッチ。 | |
- ドロップしたスクリプトがエラーを起こしても sys.path 先頭にゴミが残らないようにする。 | |
- ドロップしたスクリプトが sys.modules に残らないようにする。 | |
""" | |
module = _getOrigModule() | |
origFunc = module._executeDroppedPythonFile | |
def executeDroppedPythonFile(*args): | |
try: | |
origFunc(*args) | |
except: | |
sys.path.pop(0) | |
raise | |
finally: | |
_cleanModules(_splitext(args[0])[0]) | |
module.executeDroppedPythonFile = executeDroppedPythonFile | |
def applyOverridePatch(): | |
u""" | |
実装を丸ごと置き換えるパッチ。 | |
- 実行にあたって、そもそも sys.path 先頭にパスを追加しない。 | |
- ドロップしたスクリプトが sys.modules に残らないようにする。 | |
- 関数 onMayaDroppedPythonFile が無くても警告を出さない。 | |
""" | |
import maya.cmds as cmds | |
import imp | |
from imp import load_module | |
descDict = dict([(d[0], d) for d in imp.get_suffixes()]) | |
module = _getOrigModule() | |
def executeDroppedPythonFile(droppedFile, obj): | |
theModuleName, suffix = _splitext(droppedFile) | |
desc = descDict.get(suffix) | |
if not desc: | |
return False | |
fp = open(droppedFile, desc[1]) | |
if fp: | |
try: | |
try: | |
loadedModule = load_module(theModuleName, fp, droppedFile, desc) | |
finally: | |
fp.close() | |
func = getattr(loadedModule, 'onMayaDroppedPythonFile', None) | |
if func: | |
return func(obj) | |
finally: | |
_cleanModules(theModuleName) | |
return False | |
module.executeDroppedPythonFile = executeDroppedPythonFile | |
def _getOrigModule(): | |
import maya.app.general.executeDroppedPythonFile as module | |
if not hasattr(module, '_executeDroppedPythonFile'): | |
module._executeDroppedPythonFile = module.executeDroppedPythonFile | |
return module | |
def _cleanModules(name): | |
sys.modules.pop(name, None) | |
name += '.' | |
for x in list(sys.modules): | |
if x.startswith(name): | |
del sys.modules[x] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment