-
Notifications
You must be signed in to change notification settings - Fork 371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable Hy code in the debugger #1680
Conversation
This commit provides a context manager that patches `pdb` and adds support for Hy code in `pdb`, `ipdb` and Pdb++ under Python 2.7 and 3.x.
After adding tests, this should at least close
With a little extra (and perhaps tangential REPL) work, we could get #1397 in place, as well. Also, after some upcoming macro/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lookin' good. Let's see some tests.
|
||
def hy_pdb_default(self): | ||
def _hy_pdb_default(self, line): | ||
if line[:1] == '!': line = line[1:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the condition here is equivalent to line.startswith('!')
, which seems like a clearer way to write it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these patched functions are direct copies from the [bp]db
source (a couple have slight cross-version modifications, though), but, yeah, they could be cleaned up a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, you should attribute the source of the copied code in the commit message.
else: | ||
exc_type_name = t.__name__ | ||
|
||
print('***', exc_type_name + ':', repr(v), file=self.stdout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could just write t if isinstance(t, str) else t.__name__
instead of defining exc_type_name
.
return eval(code, frame.f_globals, frame.f_locals) | ||
except: | ||
exc_info = sys.exc_info()[:2] | ||
err = traceback.format_exception_only(*exc_info)[-1].strip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise, there's no need for a local exc_info
.
# pdb.Pdb.default = _pdb_default if restore else _hy_pdb_default | ||
# pdb.Pdb._getval = _pdb_getval if restore else _hy_pdb_getval | ||
# if hasattr(pdb.Pdb, '_getval_except'): | ||
# pdb.Pdb._getval_except = _pdb_getval_except if restore else _hy_pdb_getval_except |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably don't want to commit this big block of commented-out code.
Closes hylang#142, closes hylang#1395.
PyPy raises exceptions during calls to hy 0.15.0+32.g4af87dc.dirty using PyPy(fdd60ed87e941677e8ea11acf9f1819466521bf2) 3.5.3 on Linux
=> (import inspect [tests.resources.bin.pdb [*]])
=> (inspect.findsource func2)
(['(defn func1 [x]\n', ' (print "func1")\n', ' (+ 1 x))\n', '(defn func2 [x]\n', ' (print "func2")\n', ' (func1 x))\n'], -1)
=> (inspect.getsource func2)
Traceback (most recent call last):
File "/home/bwillard/projects/code/python/hy/hy/importer.py", line 140, in hy_eval
return eval(ast_compile(expr, "<eval>", "eval"), namespace)
File "<eval>", line 1, in <module>
File "/home/bwillard/apps/anaconda3/envs/hy-dev-pypy35/lib-python/3/inspect.py", line 947, in getsource
lines, lnum = getsourcelines(object)
File "/home/bwillard/apps/anaconda3/envs/hy-dev-pypy35/lib-python/3/inspect.py", line 939, in getsourcelines
return getblock(lines[lnum:]), lnum + 1
File "/home/bwillard/apps/anaconda3/envs/hy-dev-pypy35/lib-python/3/inspect.py", line 919, in getblock
for _token in tokens:
File "/home/bwillard/apps/anaconda3/envs/hy-dev-pypy35/lib-python/3/tokenize.py", line 597, in _tokenize
raise TokenError("EOF in multi-line statement", (lnum, 0))
tokenize.TokenError: ('EOF in multi-line statement', (2, 0)) while CPython raises no exception (notice, however, that the result it gives is incomplete): hy 0.15.0+32.g4af87dc.dirty using CPython(default) 2.7.15 on Linux
=> (import inspect [tests.resources.bin.pdb [*]])
=> (inspect.findsource func2)
(['(defn func1 [x]\n', ' (print "func1")\n', ' (+ 1 x))\n', '(defn func2 [x]\n', ' (print "func2")\n', ' (func1 x))\n'], 0)
=> (inspect.getsource func2)
'(defn func1 [x]\n' This appears to be what's causing the current test failures in Travis, and it's because the debugger triggers a call to In the course of researching and testing said patches, I noticed that Comment on Patching for HyOn a somewhat related note, all this patching has me rethinking how we could accomplish the same compatibility and core Python code re-use with much less effort. In quite a few instances, the necessary patches simply wrap the use of For instance, if Hy source strings were created by the Hy interpreter and loader as a special, identifiable type (e.g. Overall, patching every piece of relevant code that calls |
Oddly, it seems that no Travis run is showing for this PR.
You're certainly welcome to try. |
I'm closing this because of the lack of follow-up. Please reopen if you want to pick this up again. |
With the context manager provided here,
pdb
(ipdb
and Pdb++) sessions started from the Hy REPL can evaluate Hy code. For example, the following is possible: