ipython - Hook the global name lookup in a python interpreter -


here thing, have proxy holding reference remote module, , put of these proxies sys.modules such can use local modules. other objects put in __builtin__ module @ remote environment (like magic variable convenience of debugging or referencing). don't want reference these vars conn.__builtin__.var, , have either replace local __builtin__ (which seems not working replace sys.modules['__builtin__'] or hook global name finding rules. how? module can overload getattr this. in interactive interpreter ipython, main module or how this? update: pointed out @nizam mohamed, yes can __main__ module, still can't modify name lookup role of it.

i'd turn local environment remote 1 (for debugging console)

update

for iterate __builtin__.__dict__ , if there name isn't in local __builtin__. add name local's __builtin__. it's not dynamic compare name lookup rule if can't find name in local __builtin__ try remote one.

here similar discussion.

and this question gives simulation of module replace object in sys.modules. won't work __builtin__ name lookup, i've tried replace __builtin__.__getattribute__ custom 1 first use original lookup followed custom 1 when failed. global name lookup of __builtin__ never called __builtin__.__getattribute__ __builtin__.__getattribute__('name') returns desired value, __builtin__.name or name never returns one.

use ast transformation of ipython shell

as @asmeurer said, can write simple ast transformer "hook" variable name lookup. base class ast.nodetransformer provide visit_name method can manipulate. need overload method redefine variables existing in remote module not locally.

the following module can used ipython extension:

testast.py

import ast  modname = "undefined" modattr = [] user_ns = {} class mytransformer(ast.nodetransformer):     def visit_name(self, node):         if node.id in modattr , not node.id in user_ns:            return self.getname(node)         return node     def getname(self, namenode):         return ast.attribute(value=ast.name(id=modname, ctx=ast.load()),                               attr = namenode.id,                               ctx  = namenode.ctx) def magic_import(self, line):     global modname, modattr, user_ns     modname = str(line)     if not self.shell.run_code( compile('import {0}'.format(line), '<string>', 'exec') ):        user_ns = self.shell.user_ns        modattr = user_ns[line.strip()].__dict__        self.shell.ast_transformers.append(mytransformer())        print modname, 'imported'  def load_ipython_extension(ip):     ip.define_magic('magic_import', magic_import) 

dummymodule.py

robot=" world" 

usage:

in [1]: %load_ext testast in [2]: %magic_import dummymodule in [3]: print "hello" , robot hello world  in [4]: dummymodule.robot_ii = "human"  in [5]: print "hi", robot_ii hi human 

the benefit of method modification remote module takes effect because lookup done in language level , no object copied , cached.

one drawback of method not being able handle dynamic lookup. if that's important you, maybe python_line_transforms hook more suitable.


Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -