-
-
Save llllllllll/5dc03e4dcea43c61da7b to your computer and use it in GitHub Desktop.
quick nse with lazy
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
''' | |
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