Skip to content

Instantly share code, notes, and snippets.

@llllllllll
Created December 14, 2015 22:41
Show Gist options
  • Save llllllllll/5dc03e4dcea43c61da7b to your computer and use it in GitHub Desktop.
Save llllllllll/5dc03e4dcea43c61da7b to your computer and use it in GitHub Desktop.
quick nse with lazy
'''
Examples
--------
In [1]: a
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-60b725f10c9c> in <module>()
----> 1 a
NameError: name 'a' is not defined
In [2]: b = 'b'
In [3]: from a import nse
In [4]: @nse
...: def f():
...: return a
...:
In [5]: c = f()
In [6]: from lazy import parse
In [7]: parse(c)
Out[7]: Call(func=Normal(value=<function get_name at 0x7f5ab75c9ea0>), args=(Normal(value='a'), Normal(value=<frame object at 0x7f5ab723d408>)), kwargs={})
In [8]: parse(c).subs({'a': 'b'})
Out[8]: Call(func=Normal(value=<function get_name at 0x7f5ab75c9ea0>), args=(Normal(value='b'), Normal(value=<frame object at 0x7f5ab723d408>)), kwargs={})
In [9]: parse(c).subs({'a': 'b'}).lcompile()
Out[9]: 'b'
In [10]: c
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/yui/.virtualenvs/lazy/lib/python3.4/site-packages/IPython/core/prefilter.py in prefilter_lines(self, lines, continue_prompt)
348 for lnum, line in enumerate(llines) ])
349 else:
--> 350 out = self.prefilter_line(llines[0], continue_prompt)
351
352 return out
/home/yui/.virtualenvs/lazy/lib/python3.4/site-packages/IPython/core/prefilter.py in prefilter_line(self, line, continue_prompt)
323 return normal_handler.handle(line_info)
324
--> 325 prefiltered = self.prefilter_line_info(line_info)
326 # print "prefiltered line: %r" % prefiltered
327 return prefiltered
/home/yui/.virtualenvs/lazy/lib/python3.4/site-packages/IPython/core/prefilter.py in prefilter_line_info(self, line_info)
265 """
266 # print "prefilter_line_info: ", line_info
--> 267 handler = self.find_handler(line_info)
268 return handler.handle(line_info)
269
/home/yui/.virtualenvs/lazy/lib/python3.4/site-packages/IPython/core/prefilter.py in find_handler(self, line_info)
272 for checker in self.checkers:
273 if checker.enabled:
--> 274 handler = checker.check(line_info)
275 if handler:
276 return handler
/home/yui/.virtualenvs/lazy/lib/python3.4/site-packages/IPython/core/prefilter.py in check(self, line_info)
429 def check(self, line_info):
430 obj = self.shell.user_ns.get(line_info.ifun)
--> 431 if isinstance(obj, Macro):
432 return self.prefilter_manager.get_handler_by_name('macro')
433 else:
/home/yui/projects/tmp/a.py in get_name(name, frame)
38 return getattr(builtins, name)
39 except AttributeError:
---> 40 raise NameError('name %r is not defined' % name) from None
41
42
NameError: name 'a' is not defined
'''
import builtins
from functools import partial
from sys import _getframe
from codetransformer import instructions, pattern
from lazy import thunk, strict, lazy_function
from lazy.bytecode import all_startcodes
from lazy.utils import instance
def get_name(name, frame):
"""Retrieve the value named `name` in the given stackframe.
Parameters
----------
name : str
The name to look up.
frame : frame
The stackframe to look up `name` in.
Returns
-------
val : any
The value bound to `name` in `frame`.
Raises
------
NameError
When `name` is not bound.
"""
try:
return frame.f_locals[name]
except KeyError:
try:
return frame.f_globals[name]
except KeyError:
try:
return getattr(builtins, name)
except AttributeError:
raise NameError('name %r is not defined' % name) from None
@instance
class nse(type(lazy_function)):
@pattern(
instructions.LOAD_GLOBAL |
instructions.LOAD_NAME |
instructions.LOAD_DEREF |
instructions.LOAD_FAST,
startcodes=all_startcodes,
)
def _load_name(self, instr):
yield instructions.LOAD_CONST(partial(thunk, get_name, instr.arg))
yield instructions.LOAD_CONST(partial(_getframe, 1))
yield instructions.CALL_FUNCTION(0)
yield instructions.CALL_FUNCTION(1)
def __call__(self, *args, **kwargs):
return strict(super().__call__(*args, **kwargs))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment